R:评估一个字符串

时间:2014-01-09 15:31:35

标签: r metaprogramming shiny

事实证明,必须定义一个函数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)

2 个答案:

答案 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 - 在数据框中使用表达式。因此,如果由于某种原因你不能使用evalsubstitute(或他们的朋友,如withwithin),那么它看起来就像是答案是否定的。