48 votes

Spécifiez la police monospace dans `menu`

Langue: R. Question: puis-je spécifier une police à largeur fixe pour l' menu(..,graphics=T) fonction?

Explication:

J'ai récemment posé cette question sur la façon d'avoir un utilisateur de sélectionner une ligne d'une trame 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)

enter image description here

Je voudrais | de line-up. Ils ne sont pas sur le moment, assez juste, je n'ai pas augmenté les colonnes de la même largeur. J'ai donc utiliser format pour obtenir toutes les colonnes de même largeur (plus tard, je vais écrire du code pour déterminer automatiquement la largeur de chaque colonne, mais passons 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 )

enter image description here

Voir comment il est encore bancale? Pourtant, si je regarde df.padded, j'obtiens:

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

De sorte que chaque cellule est certainement rembourré à la même longueur.

La raison pour cela est probablement parce 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: Puis-je spécifier une police à largeur fixe pour l' menu(..,graphics=T) fonction?

Mise à jour

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

Donc, on dirait que je vais devoir modifier tcltk options pour cela. @Jverzani:

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

enter image description here

Étant donné qu' menu(...,graphics=T) des appels tcltk::tk_select.list lorsque graphics est VRAI, je suppose que c'est une option viable, comme n'importe quelle distribution qui serait capable d'afficher le graphique d' menu , en premier lieu, aurait également tcltk sur, depuis qu'il a besoin de faire appel tk_select.list.

(En aparté, je ne peux pas trouver quelque chose dans la documentation qui pourrait me donner l'astuce pour essayer tcl('option','add',...), et encore moins que l'option a été appelé *Listbox.font!)

Une autre mise à jour -- avait un oeil de plus près à l' select.list et menu code, et il s'avère que sur Windows (ou si .Platform$GUI=='AQUA' -- c'est que Mac?), l' tcltk::tk_select.list n'est pas appelée à tous, et c'est juste un code interne à la place. C'est pourquoi modifier '*zone de liste.la police de caractère n'affectera pas cette.

Je suppose que je vais juste:

  • si tcltk est là, la charger, définir la *zone de liste.la police des services de messagerie, et d'utiliser tcltk::tk_select.list explicitement
  • si il n'y est pas, essayez menu(...,graphics=T) d'obtenir au moins une interface graphique (ce qui ne sera pas de monospace, mais c'est mieux que rien)
  • si cela ne fonctionne pas trop, puis il suffit de secours d' menu(...,graphics=F), ce qui sera certainement le travail.

Merci à tous.

1voto

reuf Points 499

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 complétera automatiquement un vecteur avec des NA si vous essayez d'indexer des éléments inexistants.

makePaddedDataFrame() trouve seulement le plus long et couvre le reste jusqu'à une longueur équivalente.

0voto

Subs Points 499

Je ne comprends pas pourquoi vous ne voulez pas utiliser de Vue(df) (obtenir les rowid, mettre le contenu dans temp. bloc de données et l'afficher à la Vue de commande)

Edit: eh bien, il suffit d'utiliser sprintf commande

Créer une fonction f pour extraire les chaînes à partir de la trame de données objet

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 sûr, les limites utilisées dans sprintf 10, 20 sont de longueur maximale pour le nombre de caractères dans la base de données de la colonne repère (a,b). Vous pouvez le modifier à réfléchir en fonction de vos données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X