2014-11-02 3 views
2

следующие работы:Как использовать строку в качестве кода R

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

Но следующий код не работает:

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

я пытался deparse (заменить), as.forumla и Eval, но они делают не работа.

+0

Вы можете сделать что-то вроде 'str =" Sepal.Length ~ Petal.Width "; участок (as.formula (str), data = iris); abline (lm (str, iris)) '. Хотя это не совсем то, что вы хотите –

+0

Может ли 'data = iris' быть также включенным в код? – rnso

+0

Возможно, можно использовать некоторые очень неприятные комбинации 'parse' /' deparse'/'quote' /' ... '. Или используя какой-то внешний пакет, но я могу ошибаться здесь –

ответ

2

Использование str от вопроса попробуйте следующее:

# 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)) 

Или попробуйте это:

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

Обратите внимание, что этот подход может справиться с ситуацией, где есть запятые в качестве аргумента (в отличие от аргумента разделители) и не использует никаких внешних пакетов.

2

Попробуйте разобрать аргументы и создать их:

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) 
} 

Затем вызовите его:

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

У этого есть проблемы, если в аргументе есть запятая, например. если 'main =" Sepal.Length, Sepal.Length "' является частью строки. –

2

Вот еще одна альтернатива. Вы можете использовать объект call для представления аргумента data, а затем оценить его в списке аргументов.

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

Похоже, что это альтернативное решение также будет работать с оригинальным str вектором.

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)) 
}) 
Смежные вопросы