【问题标题】:using lm(my_formula) inside [.data.table's j在 [.data.table's j 中使用 lm(my_formula)
【发布时间】:2013-10-11 06:25:55
【问题描述】:

我已经养成了访问 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 工作?

在这种情况下,我使用的是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()

【问题讨论】:

  • 试试DT[, lm(frm, .SD)] (see here)。
  • 不确定这是否适合您的实际用例,但以下方法确实有效m &lt;- quote(lm(x~y)); DT[,eval(m)]
  • 它失败了,因为 x 和 y 没有在您的 j 中使用,并且因为通常 data.table 只构造它可以检测到正在使用的那些列(并且因为它之前只能是那么聪明变得无所不能;))-我还没有尝试过,但是我认为即使您这样做{x; y; lm(frm)}也可以。也许这里有一个 FR 使用.SDcols 来指示使用的列,即使没有.SD
  • j 寻找他们是一个非常抽象的陈述,需要对您的j 所做的事情有一个人工智能级别的理解。我有点惊讶地明确使用xy 没有这样做,我一定是误解了根本问题。 Re FR:请添加。
  • 啊,我现在明白了,这是一个lm 特有的问题——它在公式的环境中寻找这些变量,所以将变量添加到j 环境中(通过使用他们不知何故)没有帮助,因为公式环境在这里是.GlobalEnv

标签: r scope data.table


【解决方案1】:

lm 的工作方式是查找在所提供公式的环境中使用的变量。由于您在全局环境中创建公式,它不会在 j-expression 环境中查找,因此使精确表达式 lm(frm) 起作用的唯一方法是将适当的变量添加到正确的环境中:

DT[, {assign('x', x, environment(frm));
      assign('y', y, environment(frm));
      lm(frm)}]

现在显然这不是一个很好的解决方案,Arun 和 Josh 的建议要好得多,我只是把它放在这里是为了理解手头的问题。

edit 另一种(可能更变态,而且相当脆弱)的方法是更改​​手头公式的环境(我在这里永久执行此操作,但您可以将其还原或复制它然后去做):

DT[, {setattr(frm, '.Environment', get('SDenv', parent.frame(2))); lm(frm)}]

顺便说一句,这里发生了一件有趣的事情 - 每当您在 j-表达式中使用 get 时,所有变量都会被构造(所以如果可以避免,不要使用它) ,这就是为什么我不需要以某种方式也使用xydata.table 知道需要这些变量。

【讨论】:

  • 不是任何人都会选择使用的解决方案,但几乎正是我想要的。谢谢!
  • 一个有效的函数示例,而类似的 j 评估无效:expr &lt;- expression(x1~y1); bah2 &lt;- function(){ x1 &lt;- DT$x; y1 &lt;- DT$y; lm(eval(expr)); }; bah2(); DT[,lm(eval(expr))]
  • @Frank 如果您下载最新版本,这将起作用:expr &lt;- quote(x ~ y); DT[, lm(eval(expr))] - 请参阅:stackoverflow.com/questions/15913832/…
猜你喜欢
  • 2014-03-02
  • 2011-07-25
  • 2014-09-06
  • 2021-11-20
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2021-04-04
  • 2013-05-31
相关资源
最近更新 更多