letras - Especificar fuente monoespaciada en `menu`
fuentes para css (2)
Idioma: R. Pregunta: ¿Puedo especificar una fuente de ancho fijo para la función del menu(..,graphics=T)
?
Explicación:
Hace poco hice esta pregunta sobre cómo hacer que un usuario seleccione una fila de un marco de datos interactivamente:
df <- data.frame(a=c(9,10),b=c(''hello'',''bananas''))
df.text <- apply( df, 1, paste, collapse=" | " )
menu(df.text,graphics=T)
Me gustaria el |
alinear. No lo hacen en este momento; bastante justo, no he rellenado las columnas al mismo ancho. Así que uso el format
para hacer que cada columna tenga el mismo ancho (más adelante escribiré un código para determinar automáticamente el ancho por columna, pero ignoremos eso por ahora):
df.padded <- apply(df,2,format,width=8)
df.padded.text <- apply( df.padded, 1, paste, collapse=" | ")
menu( df.padded.text,graphics=T )
¿Ves cómo sigue siendo malo? Sin embargo, si miro df.padded
, obtengo:
> df.padded
a b
[1,] " 9 " "hello "
[2,] "10 " "bananas "
Así que cada celda es definitivamente rellenada a la misma longitud.
La razón de esto es probablemente porque la fuente predeterminada para esto (en mi sistema, Linux) no tiene un ancho fijo.
Entonces, mi pregunta es: ¿Puedo especificar una fuente de ancho fijo para la función del menu(..,graphics=T)
?
Actualizar
@RichieCotton notó que si miras el menu
con graphics=T
, llama a select.list
, que a su vez llama a tcltk::tk_select.list
.
Así que parece que tendré que modificar tcltk
opciones de tcltk
para esto. De @jverzani:
library(tcltk)
tcl("option", "add", "*Listbox.font", "courier 10")
menu(df.padded.text,graphics=T)
Dado que el menu(...,graphics=T)
llama a tcltk::tk_select.list
cuando los graphics
son VERDADEROS, supongo que esta es una opción viable, ya que cualquier distro que sea capaz de mostrar el menu
gráfico en primer lugar también tendría tcltk
, ya que necesita llamar a tk_select.list
.
(Aparte de eso, no puedo encontrar nada en la documentación que me ayude a probar tcl(''option'',''add'',...)
, por no hablar de que la opción se llamó *Listbox.font
!)
Otra actualización : select.list
cerca el código select.list
y del menu
, y aparece en Windows (o si .Platform$GUI==''AQUA''
- ¿es esa Mac?), tcltk::tk_select.list
no se llama en absoluto, y es solo un código interno en su lugar. Por lo tanto, modificar ''* Listbox.font'' no afectará esto.
Supongo que voy a:
- si tcltk está allí, cárguelo, configure el * Listbox.font en courier, y use
tcltk::tk_select.list
explícitamente - si no está allí, pruebe el
menu(...,graphics=T)
para obtener al menos una interfaz gráfica (que no será monoespacial, pero es mejor que nada) - si eso también falla, simplemente retroceda al
menu(...,graphics=F)
, que definitivamente funcionará.
Gracias a todos.
No entiendo por qué no quiere usar View (df) (obtenga el rowid, coloque el contenido en el marco de datos de temperatura y muéstrelo con el comando View)
Edit: bueno, solo usa el comando sprintf
Cree una función f para extraer las cadenas del objeto de marco de datos
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)
Por supuesto, los límites utilizados en sprintf 10, 20 son la longitud máxima para el número de caracteres en la columna del marco de datos (a, b). Puedes cambiarlo para reflejarlo de acuerdo a tus datos.
Otro enfoque para el relleno:
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 función na.pad()
explota el hecho de que R rellenará automáticamente un vector con NA si intentas indexar elementos no existentes.
makePaddedDataFrame()
solo encuentra el más largo y rellena el resto hasta una longitud correspondiente.