Spécifiez la police monospace dans `menu`

Langue: R. Question: Puis-je spécifier une police de largeur fixe pour la fonction de menu(..,graphics=T) ?

Explication:

J’ai récemment posé cette question sur la manière dont un utilisateur peut sélectionner une ligne d’un bloc de données de manière interactive:

 df <- data.frame(a=c(9,10),b=c('hello','bananas')) df.text <- apply( df, 1, paste, collapse=" | " ) menu(df.text,graphics=T) 

entrer la description de l'image ici

Je voudrais le | faire la queue Ils ne le font pas pour le moment; assez juste, je n’ai pas rempli les colonnes de la même largeur. Donc, j’utilise format pour obtenir chaque colonne à la même largeur (plus tard, j’écrirai du code pour déterminer automatiquement la largeur par colonne, mais ignorons cela pour l’instant):

 df.padded <- apply(df,2,format,width=8) df.padded.text <- apply( df.padded, 1, paste, collapse=" | ") menu( df.padded.text,graphics=T ) 

entrer la description de l'image ici

Voyez comment c’est encore vain? Pourtant, si je regarde df.padded , je reçois:

 > df.padded ab [1,] " 9 " "hello " [2,] "10 " "bananas " 

Ainsi, chaque cellule est définitivement remplie à la même longueur.

La raison en est probablement que la police par défaut (sur mon système de toute façon, Linux) n’est pas de largeur fixe.

Donc, ma question est la suivante: puis-je spécifier une police de largeur fixe pour la fonction de menu(..,graphics=T) ?

Mettre à jour

@RichieCotton a remarqué que si vous regardez le menu avec des graphics=T il appelle select.list , qui à son tour appelle tcltk::tk_select.list .

Il semble donc que je tcltk modifier les options tcltk pour cela. De @jverzani:

 library(tcltk) tcl("option", "add", "*Listbox.font", "courier 10") menu(df.padded.text,graphics=T) 

entrer la description de l'image ici

Étant donné que le menu(...,graphics=T) appelle tcltk::tk_select.list lorsque le graphics est VRAI, je pense que c’est une option viable, comme toute dissortingbution capable d’afficher le menu graphique en premier lieu. aurait également tcltk dessus, car il doit appeler tk_select.list .

(En passant, je ne trouve rien dans la documentation qui me donnerait le conseil d’essayer tcl('option','add',...) , encore moins que l’option s’appelait *Listbox.font !)

Une autre mise à jour – a examiné de plus près le code select.list et le menu , et menu sous Windows (ou si .Platform$GUI=='AQUA' – est-ce que ce Mac?), Le tcltk::tk_select.list n’est pas appelé du tout, et c’est juste un code interne à la place. La modification de ‘* Listbox.font’ n’affectera donc pas cela.

Je suppose que je vais juste:

  • Si tcltk est là, chargez-le, définissez le * Listbox.font sur courier et utilisez tcltk::tk_select.list explicitement
  • si ce n’est pas le cas, essayez le menu(...,graphics=T) pour au moins obtenir une interface graphique (qui ne sera pas monospace, mais vaut mieux que rien)
  • Si cela échoue aussi, alors il suffit de revenir au menu(...,graphics=F) , qui fonctionnera certainement.

Merci a tous.

Une autre approche du rembourrage:

 na.pad <- function(x,len){ x[1:len] } makePaddedDataFrame <- function(l,...){ maxlen <- max(sapply(l,length)) data.frame(lapply(l,na.pad,len=maxlen),...) } x = c(rep("one",2)) y = c(rep("two",10)) z = c(rep("three",5)) makePaddedDataFrame(list(x=x,y=y,z=z)) 

La fonction na.pad() exploite le fait que R remplira automatiquement un vecteur avec des NA si vous essayez d'indexer des éléments inexistants.

makePaddedDataFrame() trouve simplement le plus long et ajoute le rest à une longueur correspondante.

Je ne comprends pas pourquoi vous ne voulez pas utiliser View (df) (récupérez le rowid, mettez le contenu dans le bloc de données temp et affichez-le avec la commande View)

Edit: bien, utilisez simplement la commande sprintf

Créez une fonction f pour extraire les chaînes de l’object du bloc de données

 f <- function(x,sep1) { sep1=format(sep1,width=8) xa<-gsub(" ","",as.character(x[1])) a1 <- nchar(xa) xa=format(xa,width=8) xb=gsub(" ","",as.character(x[2])) b1 <- nchar(xb) xb=format(xb,width=8) format1=paste("%-",10-a1,"s%s%-",20-b1,"s",sep="") concat=sprintf(format1,xa,sep1,xb) concat } 

df <- data.frame(a=c(9,10),b=c('hello','bananas'))

df.text <- apply( df, 1, f,sep1="|")

menu(df.text,graphics=T)

Bien entendu, les limites utilisées dans le sprintf 10, 20 sont la longueur maximale du nombre de caractères dans la colonne frame de données (a, b). Vous pouvez le changer pour le refléter en fonction de vos données.