【问题标题】:Subset row and column at the same time同时子集行和列
【发布时间】:2012-08-03 12:05:07
【问题描述】:

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]

【问题讨论】:

  • 我无法运行dt[list(12)]:错误:Error in `[.data.table`(dt, list(12)) : typeof x.a (integer) != typeof i.V1 (double)。我使用 data.table 版本 1.8.0
  • 但这有效并且非常清楚:dt[a == 12]dt[a == 12, b]
  • @cafe876,我相信 data.table 手册建议不要使用这种语法,因为它会阻止二进制搜索并需要顺序搜索。仍然是一个很好的语法,性能不是很重要,所以也许你最好把这个评论变成一个答案。
  • 关于我的第一条评论:在 data.table 1.8.0 中,dt[J(12)] 在您的示例中执行 dt[list(12)] 的操作,但添加“indx”列略有不同...跨度>

标签: r data.table


【解决方案1】:

关于这个问题:

为什么同时为行和列设置一个 data.table 的子集总是包含键值和计算结果,有什么好的理由吗?

我相信(对我来说足够好)的原因仅仅是 Matthew Dowle 还没有开始添加该选项(可能是因为他已优先处理更有用的功能,例如":= 与")。

my answer here 之后的 cmets 中,Matthew 似乎表明它在他的 TODO 列表中,并指出“[这] 是添加 dropdrop=TRUE 将做的事情(具有速度优势)”。

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

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

【讨论】:

  • 是的,完全正确。该功能是FR#1757
  • 从 R-Forge 导出到 GitHub 后,现在是 FR#648
【解决方案2】:

一种可能性是使用:

dt[a == 12]

dt[a == 12, b]

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


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

来自新闻:

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

【讨论】:

  • 重新附加问题:也许但仅在非常遥远的将来。 v1.8.2 现在有一个datatable.optimize 功能,它对j 进行了一些优化;例如通过自动将表达式转换为更快的形式(根据 data.table wiki),meanlapply(.SD,...) 更快。如果人们喜欢它并且没有出现小精灵,那么该主题可以继续将a==2 转换为J(12) 如果key(dt)[1]=="a"。但还有许多其他事情是更高优先级的。
猜你喜欢
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
相关资源
最近更新 更多