意识到使用动态变量名称的危险,我试图循环使用varios回归模型,其中选择了不同的变量规范.通常!!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
Run Code Online (Sandbox Code Playgroud)
我的理解是!!rlang::sym(var))获取var(即x1)的值并将其放入代码中,R认为这是一个变量(不是char).我似乎错了.任何人都可以开导我吗?
1)只需使用lm(df2)或如果lm有超出问题中显示的其他列,但我们只想回归x1x2回归然后
df3 <- df2[c("y", var, "x2")]
lm(df3)
Run Code Online (Sandbox Code Playgroud)
以下是可选的,仅当公式出现在输出中就如同已明确给出一样重要时才适用。计算公式fo,然后lm按第二行运行:
fo <- formula(model.frame(df3))
fm <- do.call("lm", list(fo, quote(df3)))
Run Code Online (Sandbox Code Playgroud)
或者只是跑lm像下面的第一行一样运行,然后像第二行一样将公式写入其中:
fm <- lm(df3)
fm$call <- formula(model.frame(df3))
Run Code Online (Sandbox Code Playgroud)
任何一个都给出这个:
> fm
Call:
lm(formula = y ~ x1 + x2, data = df3)
Coefficients:
(Intercept) x1 x2
0.44752 0.04278 0.05011
Run Code Online (Sandbox Code Playgroud)
2) 字符串 lm接受公式的字符串,因此这也有效。这fn$会导致字符参数中发生替换。
library(gsubfn)
fn$lm("y ~ $var + x2", quote(df2))
Run Code Online (Sandbox Code Playgroud)
或者以更多涉及代码为代价,没有 gsubfn:
do.call("lm", list(sprintf("y ~ %s + x2", var), quote(df2)))
Run Code Online (Sandbox Code Playgroud)
或者,如果您不关心公式在没有var替换的情况下显示,那么只需:
lm(sprintf("y ~ %s + x2", var), df2)
Run Code Online (Sandbox Code Playgroud)
就个人而言,我喜欢用语言进行一些计算.对我来说,结合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
Run Code Online (Sandbox Code Playgroud)
我发现这优于任何没有显示相同调用的方法summary(lm(y ~ x1+x2, data=df2)).