R的deparse(substitute(var))的相反操作是什么?

9

我目前正在使用tkrplot库中的rp.slider在循环中调用多个参数,例如:

rp.slider(rpplot, param1)
rp.slider(rpplot, param2)

理想情况下,我希望能在循环中完成这个操作,例如:

for(i in 1:10) 
  rp.slider(rpplot, foo(paste(param,i,sep="")))

foo将把字符串编码为变量名(符号?)。rp.slider使用deparse(substitute(var))将参数转换为字符串。是否有一个foo函数可以让我做到这一点?我尝试了as.symbolas.nameparse等方法,但都没有成功。

非常感谢您的帮助!


为了澄清,deparse(substitute(x))返回[1] "x" - 我想要一种从字符串返回相同输出的方法,即哪个foo对于输入deparse(substitute(foo("x")))输出[1] "x"?这是可能的吗?


澄清一下,deparse(substitute(x)) 返回 [1] "x" - 我想要一种从字符串返回相同输出的方法,即 foo 对于输入 deparse(substitute(foo("x"))) 输出 [1] "x" 的方式是什么?这可能吗? - daveslanted
1
你应该尽量避免使用循环... - aL3xa
1
@aL3xa:在绘图时,大多数情况下使用apply函数族是不可行的。apply函数在本地环境中工作,并且与绘图函数结合使用时会产生奇怪的结果。 - Joris Meys
plyr函数族是另一个可行的选择。我还喜欢failwith选项,它为当特定绘图不按预期工作时提供了故障保护。 - Chase
2个回答

20

尝试使用eval(parse(text=...))eval(substitute(...))

parse(text=...)将字符串转换为表达式,eval计算表达式。一定要使用text参数,因为parse通常会寻找文件。忽略这点是常见的错误。另请参阅?parse?eval

> a <- 10
> x <- deparse(substitute(a))
> eval(parse(text=x))
[1] 10
为了展示如何使用它,你需要调整你的代码:
for(i in 1:10)
  eval(parse(text=paste("rp.slider(rpplot,param",i,")",sep="")))

substitute函数会将语言对象中的值替换为第二个参数所给定的字符串:

for(i in 1:10)
  eval(
    substitute(
      rp.slider(rpplot,x),
      list(x=as.name(paste("param",i,sep="")))
    )
  )

或者,使用帮助文件中的示例:

library(rpanel)
rpplot <- rp.control(title = "Demonstration of rp.tkrplot", h = 1,j=1)

redraw <- function(panel) {
  rp.tkrreplot(panel, tkrp)
}
x <- c('h','j')
rp.tkrplot(rpplot, tkrp, function(panel) plot((1:20)^panel$j, (1:20)^panel$h))

eval(parse(text=paste("rp.slider(rpplot, ",x[1]," , action = redraw,
    from = 0.05, to = 2.00, resolution = 0.05)")))

eval(
  substitute(
    rp.slider(rpplot, x, action=redraw, from=0.05, to=2.00, resolution=0.05),
    list(x = as.name(x[2]))
  )
)
这是必要的原因可以在rp.slider的源代码中找到。函数内获取变量名的构造不是R中使用的标准构造。事实上,由于这个原因,“deparse(substitute())”的使用被强烈反对。对于大多数函数来说,as.expression("x")可以用于使用变量名获取变量。然而,rpanel软件包的作者却使这种方式不可能。

1
@daveslanted:正如上面的代码所示,它完美地运行。如果您无法使其运行,则是因为还有其他问题。请注意,您只需要使用parse(text=...)来获取在函数内使用的表达式,就像上面解释的那样。 - Joris Meys
我尝试了 rp.slider(rpplot, eval(parse(text=param1))) 但是它给出了上述错误。请查看我的问题澄清 - 如果我运行 deparse(substitute(eval(parse(text="x")))),我会得到 [1] "eval(parse(text = \"x\"))"。我不确定我所问的是否可能,因为似乎在内部函数调用之前评估了 deparse/substitute?再次感谢。 - daveslanted
@daveslanted:你运行 y <- deparse(substitute(x))eval(parse(text="y"))。如果你读一下帮助文件,你就会发现 substitute 函数中的 所有东西 都被转换成字符串了。你不能嵌套这些东西。试试我给你的代码,看看是否可行。 - Joris Meys
您在编辑中的列表构造很好,但参数尚未定义 - 它们在回调函数中用作引用。请参见以下示例:http://rss.acs.unt.edu/Rdoc/library/rpanel/html/rp.tkrplot.html - 最后一行中的变量h是我想要在循环/sapply中引用的字符串。非常感谢。 - daveslanted
@daveslanted:我修改了解析结构以解析完整的调用。应该可以工作。请参见编辑后的答案。 - Joris Meys
显示剩余10条评论

0

rp.slider函数看起来是在rpanel中而不是tkrplot。

一个可能的替代方案是使用TeachingDemos包中的tkexamp函数,它基于列表构造了一个基于tktplot的绘图tk gui,您可以在循环中构造列表,然后调用tkexamp。或者,您可以查看tkexamp代码,看看它如何解析列表(在循环中)以创建tk控件,尽管浏览代码可能会让你望而却步。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接