R: объединить строки в один объект формулы - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть символьный объект, который описывает управляющие переменные для регрессионной модели.Я не могу динамически ссылаться на них правильно, когда существует более одной управляющей переменной.Рассмотрим следующий пример:

x1 = runif(1000); x2 = runif(1000); x3 = runif(1000); e = runif(1000)
y = 2*x1+3*x2+x3+ e
df = data.frame(y, x1,x2,x3)

# define formula inputs
depvar =as.symbol("y")
variableofinterest = as.symbol("x1")
control1 = as.symbol('x2')
control2 = as.symbol('x2+x3')

# this works
eval(bquote(lm(.(depvar)~ .(variableofinterest) + .(control1) , data = df)))

# this does not
eval(bquote(lm(.(depvar)~ .(variableofinterest) + .(control2) , data = df)))

Это не работает, поскольку в фрейме данных, очевидно, нет переменной x2+x3, но как я могу распутать их, чтобы ссылаться правильно, когда входные данные control = x2+x3 представляют собой заданный символ(вне моего контроля)

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Если ваша цель состоит в том, чтобы иметь только один коэффициент для x2+x3, вы должны использовать I (запретить интерпретацию / преобразование объектов).

Далее вам понадобится то, что сказал @Roland: control2 = parse(text = 'x2+x3')[[1]]

eval(bquote(lm(.(depvar)~ .(variableofinterest) + I(.(control2)) , data = df)))

Call:
lm(formula = y ~ x1 + I(x2 + x3), data = df)

Coefficients:
(Intercept)           x1   I(x2 + x3)  
      0.4899       2.0157       2.0342 

В противном случае, если вы не хотите работать с eval, as.symbol, bquote и .( ), вы можете использовать as.formula и paste0.

# define formula inputs
depvar = "y"
variableofinterest = "x1"
control1 = 'x2'
control2 = 'I(x2+x3)'

lm(as.formula(paste0(depvar,
                 "~",
                 paste0(c(variableofinterest, control2), collapse = "+"))),
   data = df)

Call:
lm(formula = as.formula(paste0(depvar, "~", paste0(c(variableofinterest, 
control2), collapse = "+"))), data = df)

Coefficients:
(Intercept)           x1   I(x2 + x3)  
     0.4899       2.0157       2.0342  
0 голосов
/ 14 декабря 2018

Мы можем quote вместо as.symbol

control2 <- quote(x2 + x3)
eval(bquote(lm(.(depvar)~ .(variableofinterest) + .(control2) , data = df)))

#Call:
#lm(formula = y ~ x1 + (x2 + x3), data = df)

#Coefficients:
#(Intercept)           x1           x2           x3  
#      0.450        2.056        3.007        1.056  

Обратите внимание, что когда мы делаем as.symbol, это добавляет backquote

as.symbol('x2 + x3')
#`x2 + x3`

сравнитьэто с quote, который возвращает language объект вместо symbol

quote(x2 + x3)
#x2 + x3

Если это уже строка, то мы можем использовать parse_expr из rlang

control2 <- rlang::parse_expr('x2 + x3')
eval(bquote(lm(.(depvar)~ .(variableofinterest) + .(control2) , data = df)))
#Call:
#lm(formula = y ~ x1 + (x2 + x3), data = df)

#Coefficients:
#(Intercept)           x1           x2           x3  
#      0.450        2.056        3.007        1.056  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...