1

我有一个描述回归模型控制变量的字符对象。每当有多个控制变量时,我都无法正确地动态引用它们。考虑以下示例:

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是给定字符(超出我的控制范围)时,我如何才能正确地解开这些以引用

4

2 回答 2

1

我们可以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_exprfromrlang

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  
于 2018-12-14T11:05:44.840 回答
1

如果您的目标是只有一个系数,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,您可以使用bquoteand 。.( )as.formulapaste0

# 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  
于 2018-12-14T11:38:42.697 回答