意识到使用动态变量名的危险,我试图遍历选择不同变量规范的varios回归模型。通常BaseController
可以很好地为我解决这种问题,但是在某种程度上它在回归中失败了。最小的示例如下:
!!rlang::sym()
我的理解是y= runif(1000)
x1 = runif(1000)
x2 = runif(1000)
df2= data.frame(y,x1,x2)
summary(lm(y ~ x1+x2, data=df2)) ## works
var = "x1"
summary(lm(y ~ !!rlang::sym(var)) +x2, data=df2) # gives an error
取!!rlang::sym(var))
的值(即x1)并将其以R认为这是一个变量(不是字符)的方式放入代码中。但是我似乎错了。谁能启发我?
答案 0 :(得分:5)
我个人喜欢用这种语言进行一些计算。对我来说,bquote
和eval
的组合是最容易记住的。
var <- as.symbol(var)
eval(bquote(summary(lm(y ~ .(var) + x2, data = df2))))
#Call:
#lm(formula = y ~ x1 + x2, data = df2)
#
#Residuals:
# Min 1Q Median 3Q Max
#-0.49298 -0.26248 -0.00046 0.24111 0.51988
#
#Coefficients:
# Estimate Std. Error t value Pr(>|t|)
#(Intercept) 0.50244 0.02480 20.258 <2e-16 ***
#x1 -0.01468 0.03161 -0.464 0.643
#x2 -0.01635 0.03227 -0.507 0.612
#---
#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
#Residual standard error: 0.2878 on 997 degrees of freedom
#Multiple R-squared: 0.0004708, Adjusted R-squared: -0.001534
#F-statistic: 0.2348 on 2 and 997 DF, p-value: 0.7908
我发现,这优于任何未显示与summary(lm(y ~ x1+x2, data=df2))
相同调用的方法。
答案 1 :(得分:4)
爆炸运算符!!
仅与“整洁”功能一起使用。它不是核心R语言的一部分。像lm()
这样的基本R函数不知道如何扩展此类运算符。相反,您需要将那些包装在可以进行扩展的函数中。 rlang::expr
就是这样的例子
rlang::expr(summary(lm(y ~ !!rlang::sym(var) + x2, data=df2)))
# summary(lm(y ~ x1 + x2, data = df2))
然后您需要使用rlang::eval_tidy
对其进行实际评估
rlang::eval_tidy(rlang::expr(summary(lm(y ~ !!rlang::sym(var) + x2, data=df2))))
# Call:
# lm(formula = y ~ x1 + x2, data = df2)
#
# Residuals:
# Min 1Q Median 3Q Max
# -0.49178 -0.25482 0.00027 0.24566 0.50730
#
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 0.4953683 0.0242949 20.390 <2e-16 ***
# x1 -0.0006298 0.0314389 -0.020 0.984
# x2 -0.0052848 0.0318073 -0.166 0.868
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.2882 on 997 degrees of freedom
# Multiple R-squared: 2.796e-05, Adjusted R-squared: -0.001978
# F-statistic: 0.01394 on 2 and 997 DF, p-value: 0.9862
您可以看到此版本将扩展的公式保留在模型对象中。
答案 2 :(得分:3)
1)只需使用lm(df2)
,或者如果lm
除了问题中显示的内容之外还有其他列,但我们只想在x1
和{ {1}}然后
x2
以下是可选的,并且仅在重要的是要像已明确给出公式一样在输出中显示公式时才适用。
使用下面的第一行计算公式df3 <- df2[c("y", var, "x2")]
lm(df3)
,然后像第二行一样运行fo
:
lm
或仅按照下面第一行的方式运行fo <- formula(model.frame(df3))
fm <- do.call("lm", list(fo, quote(df3)))
,然后像第二行一样将公式写入其中:
lm
任何一个都给出这个:
fm <- lm(df3)
fm$call <- formula(model.frame(df3))
2)字符串 > fm
Call:
lm(formula = y ~ x1 + x2, data = df3)
Coefficients:
(Intercept) x1 x2
0.44752 0.04278 0.05011
接受公式的字符串,因此也可以使用。 lm
导致字符参数中出现替换。
fn$
或以更多涉及的代码为代价,而没有gsubfn:
library(gsubfn)
fn$lm("y ~ $var + x2", quote(df2))
或者如果您不在乎公式是否显示不替换do.call("lm", list(sprintf("y ~ %s + x2", var), quote(df2)))
,则只需:
var