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.