如何将变量传递给data.table [J()]

时间:2012-12-17 20:29:45

标签: r optimization data.table

我是(完全奇妙的)data.table软件包的新手,似乎已经陷入了一个非常基本的,有些奇怪的问题。我无法发布我正在使用的确切数据集,为此我道歉 - 但我认为这个问题非常简单,可以说明这一点仍然非常清楚。

假设我有一个像这样的data.table,使用键x:

set1
   x y
1: 1 a
2: 1 b
3: 1 c
4: 2 a

我想返回包含set1所有行的x == 1子集。这在data.table中非常简单:set1[J(1)]。巴姆。完成。我也可以指定z <- 1,并致电set1[J(z)]。再次:效果很好。

...除非我尝试将其扩展到我的实际数据集,其中包含~6M行。当我打电话给set1[J(1674)]时,我会收到78排的回报,这正是我正在寻找的。但我需要能够查找(字面上)这些子集中的4M。当我将要搜索的值分配给变量id <- 1674时,并调用set1[J(id)] ... R几乎取消了我的桌面。

很明显某些东西我不明白是在data.table引擎盖下进行的,但是我还没弄清楚是什么。谷歌搜索和浏览Stack Overflow表明这应该工作。出于纯粹的奇想,我试过了:

id <- quote(1674)
set1[J(eval(id))]

......但这远远更糟糕。什么......发生了什么事?

1 个答案:

答案 0 :(得分:3)

[@mnel在我写作时打败了我...]

几乎可以肯定,set1的一列恰好被称为"id";即,

isTRUE("id" %in% names(set1))

导致set1[J(id)]自我加入set1$idset1,忽略调用范围中的id

如果是这样,有几种方法可以避免范围问题,例如:

.id = <your 4M ids>
set1[J(.id)]

或使用在调用范围中评估单个名称i的事实:

JDT=J(id); set1[JDT]

eval在调用范围时也是eval':

set1[eval(J(id))]

或者,我们确实希望更清晰,更强大和更轻松,因此我们想要添加..

set1[..(J(id))]     # .. alias for eval

或者也许:

set1[J(..id)]

其中..从文件系统..借用其含义,意味着一级升级。如果..是符号的前缀,那么您可以执行以下操作:

DT[colB==..id]

其中==用于说明。在该示例中,colB应该是列名,..id将在调用范围中找到id(一级)。我们的想法是,代码的读者可以清楚地了解程序员的意图。