在菜单中指定等宽字体

语言:R.问题: 我可以指定menu(..,graphics=T)固定宽度字体menu(..,graphics=T)吗?

说明:

我最近问这个问题如何让用户交互地select一行数据框:

 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 ab [1,] " 9 " "hello " [2,] "10 " "bananas " 

所以每个单元格肯定被填充到相同的长度。

原因可能是因为这个(在我的系统上,Linux)的默认字体不是固定的宽度。

所以我的问题是: 我可以指定固定宽度的menu(..,graphics=T)function的字体?

更新

@RichieCotton注意到,如果你看graphics=T menu ,它调用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时,我的猜测是,这是一个可行的select,因为任何发行版将能够显示graphicsmenu在第一位也会有tcltk ,因为它需要调用tk_select.list

*Listbox.font说一下,在文档中找不到任何提示尝试tcl('option','add',...) ,更不用说该选项被称为*Listbox.font !)

另一个更新 – 仔细看看select.listmenu代码,结果在Windows上(或者.Platform$GUI=='AQUA' – 是Mac吗?), tcltk::tk_select.list根本没有被调用,而只是一些内部代码。 所以修改'* Listbox.font'不会影响到这一点。

我想我只会:

  • 如果tcltk在那里,加载它,设置* Listbox.font快递,明确使用tcltk::tk_select.list
  • 如果它不在那里,尝试menu(...,graphics=T) ,至less得到一个graphics界面(这将不是等宽,但总比没有好)
  • 如果这也失败了,那么只需要回退到menu(...,graphics=F) ,这肯定会起作用。

谢谢大家。

另一种填充方法:

 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()只find最长的一个,并将其余的makePaddedDataFrame()到一个匹配的长度。

我不明白你为什么不想使用View(df)(获取rowid,把内容放入temp数据框并用View命令显示它)

编辑:好吧,只需使用sprintf命令

创build一个函数f从数据框对象中提取string

 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中使用的限制是dataframe列(a,b)中字符数的最大长度。 您可以根据您的数据进行更改以反映出来。

Interesting Posts