子集行和列同时

时间:2012-08-03 12:05:08

标签: r data.table

我对data.table的工作方式感到有些惊讶:

> library(data.table)
data.table 1.8.2  For help type: help("data.table")
> dt <- data.table(a=11:20, b=21:30, c=31:40, key="a")
> dt[list(12)]
    a  b  c
1: 12 22 32
> dt[list(12), b]
    a  b
1: 12 22
> dt[list(12)][,b]
[1] 22

我要做的是获取与选择匹配的行中的单个列(或表达式)的值。我看到我必须将密钥作为列表传递,因为原始数字表示行号而不是键值。所以上面的第一个对我来说很清楚。但是为什么第二个和第二个子集表达产生不同的结果似乎让我感到困惑。我想获得第三个结果,但是能够以第二种方式编写它。

有没有什么理由可以同时为行和列分组data.table总是包含键值和计算结果?除了上面的双子集之外,是否有一种语法上较短的方法来获得单个结果?

我在R 2.15.1上使用data.table 1.8.2。如果你无法重现我的例子,你可以考虑一个因素作为关键:

dt <- data.table(a=paste("a", 11:20, sep=""), b=21:30, c=31:40, key="a")
dt["a11", b]

2 个答案:

答案 0 :(得分:7)

关于这个问题:

  

为什么同时对行和列的data.table进行子集化是否总是包含键值以及计算结果有什么好的理由?

我认为(对我来说足够好)的原因很简单,马修道尔还没有尚未开始添加该选项(可能是因为他优先考虑更有用的功能,如“:= with by”)。

my answer here之后的评论中,马修似乎表明它在他的TODO清单上,注意到“[this]是drop=TRUEdrop时会做的事情(具有速度优势) } 被添加”。

在此之前,以下任何一项都可以完成工作:

dt[list(12)][,b]
# [1] 22
dt[list(12)][[2]]
# [1] 22
dt[dt[list(12), which=TRUE], b]
# [1] 22

答案 1 :(得分:5)

一种可能性是使用:

dt[a == 12]

dt[a == 12, b]

这将按预期工作,但它会阻止二进制搜索并需要顺序搜索(是否有计划更改此行为?),使其可能更慢。


2014年9月更新:现在在v1.9.3

来自新闻:

  

DT[column==values]现在已优化为在DT时使用key(DT)[1]=="column"的密钥,否则会自动添加辅助密钥(也称为索引),以便下一个DT[column==values]更快。 DT[column %in% values]是等价的;即,==%in%都接受矢量值。无需更改代码;现有代码应自动受益。可以使用set2key()手动添加辅助密钥,并使用key2()检查是否存在。这些优化和函数名称/参数是实验性的,可以使用options(datatable.auto.index=FALSE)关闭。