Укажите моноширинный шрифт в `menu`
Язык: R. Вопрос: Можно ли указать шрифт фиксированной ширины для menu(..,graphics=T)
функционировать?
Объяснение:
Недавно я задал этот вопрос о том, как заставить пользователя интерактивно выбирать строку фрейма данных:
df <- data.frame(a=c(9,10),b=c('hello','bananas'))
df.text <- apply( df, 1, paste, collapse=" | " )
menu(df.text,graphics=T)
Я хотел бы |
выстраиваться. Они не в данный момент; честно говоря, я не разложил столбцы на одинаковую ширину. Поэтому я использую format
чтобы получить каждый столбец одинаковой ширины (позже я напишу код, который автоматически определит ширину каждого столбца, но давайте пока проигнорируем это):
df.padded <- apply(df,2,format,width=8)
df.padded.text <- apply( df.padded, 1, paste, collapse=" | ")
menu( df.padded.text,graphics=T )
Видишь, как это все еще шатко? Тем не менее, если я смотрю на df.padded
, Я получил:
> df.padded
a b
[1,] " 9 " "hello "
[2,] "10 " "bananas "
Таким образом, каждая ячейка определенно имеет одинаковую длину.
Причина этого, вероятно, в том, что шрифт по умолчанию для этого (в любом случае, в моей системе, Linux) не имеет фиксированной ширины.
Поэтому мой вопрос: могу ли я указать шрифт фиксированной ширины для menu(..,graphics=T)
функционировать?
Обновить
@RichieCotton заметил, что если вы посмотрите на menu
с graphics=T
это вызывает select.list
который в свою очередь вызывает tcltk::tk_select.list
,
Похоже, мне придется изменить tcltk
варианты для этого. От @jverzani:
library(tcltk)
tcl("option", "add", "*Listbox.font", "courier 10")
menu(df.padded.text,graphics=T)
При условии menu(...,graphics=T)
звонки tcltk::tk_select.list
когда graphics
TRUE, я думаю, что это жизнеспособный вариант, как любой дистрибутив, который был бы способен отображать графический menu
в первую очередь также будет иметь tcltk
на это, так как он должен позвонить tk_select.list
,
(Кроме того, я не могу найти в документации ничего, что дало бы мне подсказку попробовать tcl('option','add',...)
не говоря уже о том, что вариант был назван *Listbox.font
!)
Еще одно обновление - присмотреться select.list
а также menu
код, а получается на винде (или если .Platform$GUI=='AQUA'
- это Mac?) tcltk::tk_select.list
вообще не вызывается, а вместо этого просто внутренний код. Поэтому изменение *Listbox.font не повлияет на это.
Я думаю, я просто:
- если есть tcltk, загрузите его, установите *Listbox.font на courier и используйте
tcltk::tk_select.list
эксплицитно - если его там нет, попробуйте
menu(...,graphics=T)
по крайней мере, получить графический интерфейс (который не будет моноширинным, но лучше, чем ничего) - если это тоже не удается, то просто отступить
menu(...,graphics=F)
, который, безусловно, будет работать.
Спасибо всем.
2 ответа
Еще один подход к заполнению:
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))
na.pad()
Функция использует тот факт, что R автоматически дополнит вектор NA, если вы попытаетесь проиндексировать несуществующие элементы.
makePaddedDataFrame()
просто находит самый длинный и дополняет остальные до соответствующей длины.
Я не понимаю, почему вы не хотите использовать View(df) (получите rowid, поместите содержимое во временный фрейм данных и отобразите его с помощью команды View)
Редактировать: ну просто используйте sprintf
команда
Создайте функцию f для извлечения строк из объекта фрейма данных
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)
Конечно, ограничения, используемые в sprintf 10, 20, представляют собой максимальную длину для количества символов в столбце фрейма данных (a,b). Вы можете изменить это, чтобы отразить это согласно вашим данным.