Reputation: 24593
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
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
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
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