即使我不需要,我也养成了j
中访问data.table列的习惯:
require(data.table)
set.seed(1); n = 10
DT <- data.table(x=rnorm(n),y=rnorm(n))
frm <- formula(x~y)
DT[,lm(x~y)] # 1 works
DT[,lm(frm)] # 2 fails
lm(frm,data=DT) # 3 what I'll do instead
我希望#2能够正常工作,因为lm
应该在DT
中搜索变量,然后在全局环境中搜索...是否有一种优雅的方法可以让像#2这样的东西工作? / p>
在这种情况下,我使用lm
,它采用“数据”参数,因此#3工作正常。
编辑。请注意,这有效:
x1 <- DT$x
y1 <- DT$y
frm1 <- formula(x1~y1)
lm(frm1)
,这也是:
rm(x1,y1)
bah <- function(){
x1 <- DT$x
y1 <- DT$y
frm1 <- formula(x1~y1)
lm(frm1)
}
bah()
EDIT2。然而,这失败了,说明了@ eddi的回答
frm1 <- formula(x1~y1)
bah1 <- function(){
x1 <- DT$x
y1 <- DT$y
lm(frm1)
}
bah1()
答案 0 :(得分:4)
lm
的工作方式是查找所提供公式环境中使用的变量。由于您在全局环境中创建公式,因此不会在j
- 表达式环境中查找,因此使精确表达式lm(frm)
工作的唯一方法是将适当的变量添加到正确的环境:
DT[, {assign('x', x, environment(frm));
assign('y', y, environment(frm));
lm(frm)}]
现在显然这不是一个很好的解决方案,Arun和Josh的建议都要好得多,而我只是把它放在这里以便了解手头的问题。
编辑另一种(可能更加变态,相当脆弱)的方式是改变手头公式的环境(我在这里永久地做,但你可以将它还原,或者复制它然后这样做):
DT[, {setattr(frm, '.Environment', get('SDenv', parent.frame(2))); lm(frm)}]
顺便说一句,这里发生了一件有趣的事情 - 无论何时在get
- 表达式中使用j
,所有变量都会被构建(所以不如果你使用它可以避免它),这就是为什么我不需要以某种方式使用x
和y
来data.table
知道那些变量是必需的。