2

我对(完全了不起的)软件包是全新的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))]

......但那远非常糟糕。什么……这是怎么回事?

4

1 回答 1

3

[@mnel 在我写作的时候打败了我……]

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

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)]

where..从文件系统的 中借用它的含义..,意思是上一级。如果..是符号的前缀,则可以执行以下操作:

DT[colB==..id]

where == is used there for illustration. In that example colB is expected to be a column name and ..id will find id in calling scope (one level up). The thinking is that that would be quite clear to the reader of the code what the programmer intended.

于 2012-12-17T21:52:48.123 回答