0

In my app user can provide "subsetting" expression (which consist of mix: variables, names stored in variable - vide args_input and subset_args_input variables) as arguments to subset/[ functions:

df_data <- data.frame("a" = c(1,1,2),
                      "b" = c(3,4,4),
                      "c" = c(5,6,7))

global_data <- list("column_to_extract" = c("b"))

args_input <- "list(df_data, df_data$a %in% c(1), global_data[['column_to_extract']])"

My expectation is to get as same result as executing:

do.call("[", list(df_data, df_data$a %in% c(1), global_data[['column_to_extract']]))

by executing this:

do.call("[", eval(parse(text=args_input)))

Also, I've tried something similar with subset:

subset_args_input <- "list(quote(df_data), quote(a %in% c(1)), quote(global_data[['column_to_extract']]))"

do.call("subset", eval(parse(text=subset_args_input)))
  1. Both approaches work, but need eval + parse, which are not safe in case user is allowed to pass any string. Question - could the same results be achieved without eval + parse combo?
  2. Could you (R users:) please have a look at above snippets - are there any unnecessary things/something against R philosophy?
RSzT
  • 307
  • 3
  • 14
  • 1
    If you let your users pass R expressions as text you need to parse that text. Obviously you shouldn't do that. I can't comment more with the available information. – Roland Aug 06 '17 at 19:45
  • @Roland: thanks for comment. I am looking for the safe solution in which user can pass: name of DF to subset, subset condition, selected "output" column/-s - all of these as strings. – RSzT Aug 06 '17 at 20:27
  • There is no safe way to do it like that because you'll have to parse and evaluate the subset condition. You need to work on the way the user input is created. For example you could use something like this, where the subsetting functions and the RHS and LHS are separate input (e.g., using a drop-down menu and two text fields): `with(df_data, eval(as.symbol(column_to_extract))[ switch(subfun, "==" = `==`, "<" = \`<\`, ">" = \`>\`, "%in%" = \`%in%\`)(eval(as.symbol(LHS)), type.convert(RHS))])`. – Roland Aug 07 '17 at 06:38
  • Ok, kind of white list with allowed expression - thank you for your comment. – RSzT Aug 07 '17 at 14:55

0 Answers0