事实证明,必须定义一个函数eval_string
,它将字符串计算为表达式(/ call)。例如,如果:
string <- 'cyl == 6 & disp > 200'
我想要:
eval_string(string, mtcars)
相当于:
eval(quote(cyl == 6 & disp > 200), mtcars)
这是我的尝试:
eval_string <- function(string, ...) eval(parse(text = string), ...)
这似乎有用,但是,我知道parse
不赞成,并且对这种类型的编程没有太多经验(无论它是什么?)。所以我的问题是:是否有更规范的方式来实现我想要的东西?要在问题背后加上一些背景信息,eval_string
将与shiny
一起使用;特别是textInput
函数。
欢呼任何帮助。
编辑:感谢评论家伙。当我使用textInput
对数据框进行分组时,在Hadley指南的帮助下,我也提出了这个解决方案:
library(pryr)
subset_with_string <- function(string, data) {
expr <- parse(text = string)[[1]]
subset_calls <- c("==", "!=", "&", "|", ">", "<", ">=", "<=", "(")
legal_call <- all(fun_calls(expr) %in% subset_calls)
if (legal_call) {
data[eval(expr, data), ]
}
else {
stop('string does not induce a legal subset call to evaluate!')
}
}
subset_with_string("(cyl == 6 & hp > 100) | gear == 4", mtcars)
subset_with_string("rm('importantFile.doc')", mtcars)
答案 0 :(得分:1)
为了避免使用eval,我在Shiny应用程序中有以下内容:
dat&lt; - try(do.call(subset,list(data,parse(text = string))),silent = TRUE)
if(!is(dat,'try-error'))return(dat)
答案 1 :(得分:0)
没有解析它就无法“评估”字符串(在当前意义上)。因此,如果您的输入是字符串,那么就无法避免parse
。
请参阅subset.data.frame
了解如何在没有字符串的情况下进行操作
[[EDIT]]但是subset.data.frame基本上是eval
- 在数据框中使用表达式。因此,如果由于某种原因你不能使用eval
和substitute
(或他们的朋友,如with
和within
),那么它看起来就像是答案是否定的。