我是(完全奇妙的)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))]
......但这远远更糟糕。什么......发生了什么事?
答案 0 :(得分:3)
[@mnel在我写作时打败了我...]
几乎可以肯定,set1
的一列恰好被称为"id"
;即,
isTRUE("id" %in% names(set1))
导致set1[J(id)]
自我加入set1$id
到set1
,忽略调用范围中的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
(一级)。我们的想法是,代码的读者可以清楚地了解程序员的意图。