Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 457
Mullefa Avatar asked Dec 07 '25 05:12

Mullefa


1 Answers

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)

like image 107
Vincent Avatar answered Dec 09 '25 08:12

Vincent



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!