【问题标题】:R data.table keyby multiple columns when chaining链接时R data.table keyby多列
【发布时间】:2015-10-05 17:56:15
【问题描述】:

我想创建一个只有两列的新数据表,并使用这两列作为键将它与另一个表连接起来。我可以这样做:

a.dt <- data.table(x = 1:3, y = 2:4)
setkey(a.dt,x,y)
key(a.dt)
# [1] "x" "y"
# ...(join)

但我不想使用setkey - 我想立即链接到联接中,即在创建表之后我想keyby 两个新变量。由于我不清楚的原因,我收到了这个错误:

a.dt <- data.table(x = 1:3, y = 2:4)[, .SD, keyby = .(x,y)]
# Error in jsub[[ii]] : attempt to select less than one element

这是我丑陋的解决方法

a.dt <- data.table(x = 1:3, y = 2:4, z = 3:5)[, .SD, keyby = .(x,y)][,z := NULL]
key(a.dt)
# [1] "x" "y"

有人可以解释为什么我不能keyby 两个变量吗?我在做一些根本上愚蠢的事情吗?

编辑:为了完整性添加会话信息

sessionInfo()
# R version 3.2.1 (2015-06-18)
# Platform: x86_64-w64-mingw32/x64 (64-bit)
# Running under: Windows 8 x64 (build 9200)

# locale:
# [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
# [4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

# attached base packages:
# [1] stats     graphics  grDevices utils     datasets  methods   base     

# other attached packages:
# [1] data.table_1.9.4 plyr_1.8.2       foreign_0.8-63  

# loaded via a namespace (and not attached):
# [1] magrittr_1.5   tools_3.2.1    reshape2_1.4.1 Rcpp_0.12.0    stringi_0.4-1  stringr_1.0.0  chron_2.3-45  

【问题讨论】:

  • 您的代码在定义 a.dt 之前有 setkey(a.dt,...)。认为这是一个错字..?
  • data.table(x = 1:3, y = 2:4, key = c("x","y")) 之前已经讨论过您所提议的内容,并且共识似乎是新功能on= 解决了这个问题:github.com/Rdatatable/data.table/issues/794
  • 谢谢,我错过了这个简单的解决方案。
  • 感谢您使用sessionInfo() 进行编辑。 1.9.4 已经有一年的历史了,最近发布的v1.9.6 中实现了几个错误修复和功能(> 180 个问题已关闭)。所以请升级。
  • 升级“正如我们所说的”:-)。非常感谢“开启”功能。

标签: r data.table


【解决方案1】:

您可以在创建 data.table 时使用 key 参数键入:

require(data.table) #v1.9.6
DT2 = data.table(x=3:4, y=4:5, w=5:6)
DT1 = data.table(x=1:3, y=2:4, z=7:9, key=c("x", "y"))[DT2]

或者,从v1.9.6 开始,您可以使用on= 参数来指定应该执行连接的列。

DT2 = data.table(a=3:4, b=4:5, w=5:6)
DT1 = data.table(x=1:3, y=2:4, z=7:9)[DT2, on=c(x="a", y="b")]

另一种方法是在 list 上使用 setDT() 以及 key 参数。

DT2 = data.table(a=3:4, b=4:5, w=5:6)
DT1 = setDT(list(x=1:3, y=2:4, z=7:9), key=c("x", "y"))[DT2]

dt[, .SD, keyby=.(x, y)] 为我返回一个 empty data.table(应该如此)。不确定您使用的是哪个版本的 data.table。这是因为.SD 默认分配所有列除了by= 中提到的列。由于有两列,并且您已将两列都提供给分组依据,.SD 为空。因此返回一个空的 data.table。如果你真的想要这种行为,你需要显式设置.SDcols,如下所示:

dt[, .SD, keyby=.(x, y), .SDcols=c("x", "y")]
# or from v1.9.6 we can also do
dt[, .SD, keyby=.(x, y), .SDcols=x:y]

但请注意,这将返回 x,y 两次。

【讨论】:

  • 谢谢阿伦,这完全回答了我的问题。
  • 嘿,抱歉。我的“更实质性”的编辑添加了一个字符;和 Jaap 的,七岁 :)
猜你喜欢
  • 2016-07-20
  • 2020-07-26
  • 2016-11-12
  • 2017-10-04
  • 1970-01-01
  • 2021-05-17
  • 2016-08-26
  • 2017-06-22
  • 2015-07-28
相关资源
最近更新 更多