我在https://cran.r-project.org/web/packages/data.table/vignettes/datatable-keys-fast-subset.html#multiple-key-point上看到了这个小插图。
我的数据是这样的:
ID TYPE MEASURE_1 MEASURE_2
1 A 3 3
1 B 4 4
1 C 5 5
1 Mean 4 4
2 A 10 1
2 B 20 2
2 C 30 3
2 Mean 20 2
当我这样做的时候…一切正常
setkey(dt, ID, TYPE)
dt[.(unique(ID), "A")] # extract SD of all IDs with Type A
dt[.(unique(ID), "B")] # extract SD of all IDs with Type B
dt[.(unique(ID), "C")] # extract SD of all IDs with Type C
每当我尝试这样做时,我想要基于第二个键的多个值的键子集,我只得到键1中唯一值的所有组合的结果,只有在向量c()
中为第二个键定义的第一个值。因此,它只接受vector中定义的第一个值,而忽略后面的所有值。
# extract SD of all IDs with one of the 3 types A/B/C
dt[.(unique(ID), c("A", "B", "C")]
# previous output is equivalent to
dt[.(unique(ID), "A")] # extract SD of all IDs with Type A
# I want/expect
dt[TYPE %in% c("A", "B", "C")]
我在这里错过了什么,或者这是我不能用键子集做的事情吗?
澄清一下:由于我不能在键子集中省略键1,因此插图要求包含unique(key1)
的第一个键。并且在key 1中定义多个键也可以正常工作。
dt[.(c(1, 2), "A")] == dt[ID %in% c(1,2) & TYPE == "A"] # TRUE
在数据中。表文档(参见help("data.table")
或https://rdatatable.gitlab.io/data.table/reference/data.table.html#arguments)中提到:
字符、列表和数据帧输入到i被转换成一个数据。表内部使用as.data.table.
因此,R(或data.frame
)中使用的经典循环规则适用。也就是说,与list(unique(ID), c("A", "B", "C"))
等价的.(unique(ID), c("A", "B", "C"))
变成:
as.data.table(list(unique(ID), c("A", "B", "C")))
,并且由于最长的列表元素的长度(c("A", "B", "C")
的长度)不是较短的元素(unique(ID)
的长度)的倍数,因此您将得到一个错误。如果您希望将unique(ID)
中的每个值与c("A", "B", "C")
中的每个元素结合使用,则应该使用CJ(unique(ID), c("A", "B", "C"))
。
所以你应该做的是dt[CJ(unique(ID), c("A", "B", "C"))]
。
请注意,dt[.(unique(ID), "A")]
工作正确,因为您只传递了第二个键的一个元素,并且它被回收以匹配unique(ID)
的长度。