我是(完全很棒的)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)]中非常简单。 am做完了我还可以分配z <- 1,然后调用set1[J(z)]。再次:效果很好。

...除非我尝试将其扩展到包含约600万行的实际数据集。当我呼叫set1[J(1674)]时,我得到的正是我想要的78行返回值。但是我需要能够(从字面上看)这些子集中的4M。当我将要搜索的值分配给变量id <- 1674并调用set1[J(id)] ... R几乎关闭了我的桌面。

显然,我不了解的事情正在data.table的幕后进行,但我一直无法弄清楚是什么。在Google堆栈溢出中进行谷歌搜索和搜索时发现这应该可行。出于纯粹的异想天开,我尝试了:

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


...但是那要糟得多。怎么回事

最佳答案

[@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。这种想法是,对于代码的读者来说,程序员的意图很清楚。

关于r - 如何通过变量将参数传递到data.table [J()],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13921670/

10-11 16:26