在“菜单”中指定等宽字体
语言: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
,而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)
当graphics
为TRUE时调用tcltk::tk_select.list
,我的猜测是这是一个可行的选择,因为任何能够显示图形的发行版menu
首先也会有 tcltk
,因为它需要调用 tk_select.list
。
(顺便说一句,我在文档中找不到任何可以提示我尝试 tcl('option','add',...) 的内容,更不用说该选项了称为 *Listbox.font
!)
另一个更新 - 仔细查看了 select.list
和 menu
代码,结果在 Windows 上(或者如果.Platform$GUI=='AQUA'
-- 是 Mac 吗?),tcltk::tk_select.list
根本没有被调用,它只是一些内部的代码代替。因此修改“*Listbox.font”不会影响这一点。
我想我会这样:
- 如果 tcltk 存在,则加载它,将 *Listbox.font 设置为 courier,
- 如果不存在,则显式使用 tcltk::tk_select.list ,尝试
menu(...,graphics=T)
至少获得一个图形界面(它不会是等宽的,但总比没有好) - 如果也失败了,那么就回退到
menu(...,graphics=F)
,这肯定会起作用。
谢谢大家。
Language: R. Question: Can I specify fixed width font for the menu(..,graphics=T)
function?
Explanation:
I recently asked this question on how to have a user select a row of a data frame interactively:
df <- data.frame(a=c(9,10),b=c('hello','bananas'))
df.text <- apply( df, 1, paste, collapse=" | " )
menu(df.text,graphics=T)
I'd like the |
to line up. They don't at the moment; fair enough, I haven't padded out the columns to the same width. So I use format
to get every column to the same width (later I'll write code to automagically determine the width per column, but let's ignore that for now):
df.padded <- apply(df,2,format,width=8)
df.padded.text <- apply( df.padded, 1, paste, collapse=" | ")
menu( df.padded.text,graphics=T )
See how it's still wonky? Yet, if I look at df.padded
, I get:
> df.padded
a b
[1,] " 9 " "hello "
[2,] "10 " "bananas "
So each cell is definitely padded out to the same length.
The reason for this is probably because the default font for this (on my system anyway, Linux) is not fixed width.
So my question is:
Can I specify fixed width font for the menu(..,graphics=T)
function?
Update
@RichieCotton noticed that if you look at menu
with graphics=T
it calls select.list
, which in turn calls tcltk::tk_select.list
.
So it looks like I'll have to modify tcltk
options for this. From @jverzani:
library(tcltk)
tcl("option", "add", "*Listbox.font", "courier 10")
menu(df.padded.text,graphics=T)
Given that menu(...,graphics=T)
calls tcltk::tk_select.list
when graphics
is TRUE, my guess is that this is a viable option, as any distro that would be capable of displaying the graphical menu
in the first place would also have tcltk
on it, since it needs to call tk_select.list
.
(As an aside, I can't find anything in the documentation that would give me the hint to try tcl('option','add',...)
, let alone that the option was called *Listbox.font
!)
Another update -- had a closer look at the select.list
and menu
code, and it turns out on Windows (or if .Platform$GUI=='AQUA'
-- is that Mac?), the tcltk::tk_select.list
isn't called at all, and it's just some internal code instead. So modifying '*Listbox.font' won't affect this.
I guess I'll just:
- if tcltk is there, load it, set the *Listbox.font to courier, and use
tcltk::tk_select.list
explicitly - if it isn't there, try
menu(...,graphics=T)
to at least get a graphical interface (which won't be monospace, but is better than nothing) - if that fails too, then just fallback to
menu(...,graphics=F)
, which will definitely work.
Thanks all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
另一种填充方法:
na.pad()
函数利用了这样一个事实:如果您尝试索引不存在的元素,R 将自动用 NA 填充向量。makePaddedDataFrame()
只是找到最长的一个并将其余的填充到匹配的长度。Another approach to padding:
The
na.pad()
function exploits the fact that R will automatically pad a vector with NAs if you try to index non-existent elements.makePaddedDataFrame()
just finds the longest one and pads the rest up to a matching length.我不明白为什么你不想使用 View(df) (获取 rowid,将内容放入临时数据框中并使用 View 命令显示它)
编辑:好吧,只需使用 sprintf command
创建一个函数 f 以从数据框对象中提取字符串
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 中使用的限制是最大的length 为数据帧列 (a,b) 中的字符数。您可以更改它以根据您的数据反映它。
I don't understand why you don't want to use View(df) (get the rowid, put the contents into temp. data frame and display it with the View command)
Edit: well, just use
sprintf
commandCreate a function f to extract the strings from the data frame object
df <- data.frame(a=c(9,10),b=c('hello','bananas'))
df.text <- apply( df, 1, f,sep1="|")
menu(df.text,graphics=T)
Of course the limits used in sprintf 10, 20 are maximum length for the number of characters in the data-frame column (a,b). You can change it to reflect it according to your data.