简体   繁体   中英

R: evaluate a string

It has proved necessary to define a function eval_string which evaluates a string as if it were an expression(/call). For example, if:

string <- 'cyl == 6 & disp > 200'

I would want:

eval_string(string, mtcars) 

to be equivalent to:

eval(quote(cyl == 6 & disp > 200), mtcars)

This is my attempt:

eval_string <- function(string, ...) eval(parse(text = string), ...)

which seems to work, however, I am aware parse is frowned upon, and do not have much experience with this type of programming (whatever it is?). So my question is: is there a more canonical way of achieving what I want? To put some context behind the question, eval_string will be used in conjunction with shiny ; in particular, the textInput function.

Cheers for any help.

EDIT: thanks for the comments guys. As I am using the textInput to subset a data frame, with help from Hadley's guide, I have come up with this solution also:

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)

To avoid using eval I have the following in a Shiny app:

dat <- try(do.call(subset, list(data,parse(text = string))), silent = TRUE)

if(!is(dat, 'try-error')) return(dat)

There's no way to "evaluate" a string (in the present sense) without parsing it. So if your input is a string then there's no way to avoid parse .

See subset.data.frame for an idea how to do it without strings

[[EDIT]] But subset.data.frame basically eval -uates an expression in a data frame. So if for some reason you're not ok with eval and substitute (or their friends like with and within ) then it looks like then answer is no.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM