rnso
rnso

Reputation: 24593

How to use string as code in R

Following works:

plot(Sepal.Length ~ Petal.Width, data = iris)
abline(lm(Sepal.Length ~ Petal.Width, data = iris))

But following code does not work:

str = "Sepal.Length ~ Petal.Width, data = iris"
plot(str)
abline(lm(str))

I tried deparse(substitute), as.forumla and eval but they do not work.

Upvotes: 2

Views: 168

Answers (3)

Rich Scriven
Rich Scriven

Reputation: 99351

Here's another alternative. You could use a call object to represent the data argument and then evaluate it in the argument list.

f <- formula("Sepal.Length ~ Petal.Width")
cl <- call("=", "data", iris)
plot(f, eval(cl))
abline(lm(f, eval(cl)))

It looks like this alternate solution will also work with the original str vector.

str <- "Sepal.Length ~ Petal.Width, data = iris"
s <- strsplit(str, ", data = ")[[1]]
with(setNames(as.list(s), c("formula", "data")), {
    getd <- get(data, parent.frame())
    plot(f <- formula(formula), data = getd)
    abline(lm(f, data = getd))
})

Upvotes: 2

G. Grothendieck
G. Grothendieck

Reputation: 269885

Using str from the question try this:

 # fun and args should each be a character string
 run <- function(fun, args) eval(parse(text = sprintf("%s(%s)", fun, args)))

 run("plot", str)
 abline(run("lm", str))

Or try this:

 `%(%` <- function(fun, args) run(deparse(substitute(fun)), args)
 plot %(% str
 abline(lm %(% str)

Note that this approach can handle the situation where there are commas in an argument (as opposed to argument separators) and does not make use of any external packages.

Upvotes: 2

agstudy
agstudy

Reputation: 121598

Try to parse arguments and create them :

fun_str<- function(fun, str_arg){
    ## split args separted by comma
    m <- as.list(strsplit(str_arg,',')[[1]])
    args  <- lapply(m,function(x){
      ## remove any extra space 
      arg = str_trim(strsplit(x,'=')[[1]])
      if (arg[1]=="data") get(arg[2],parent.frame())
      else if (grepl('~',x))  as.formula(x)
    })
    do.call(fun,args)
}

Then call it :

fun_str("plot",str)
fun_str("lm",str)

Upvotes: 2

Related Questions