【问题标题】:How to do multi-key lookups using data.table?如何使用 data.table 进行多键查找?
【发布时间】:2014-02-17 20:09:03
【问题描述】:

我正在使用 data.table 对大型数据集(45M 行,4 个 int 列)进行一些重复查找。

这就是我想做的。

library(data.table)
# generate some data, u's can show up in multiple s's
d1 <- data.table(u=rep(1:500,2), s=round(runif(1000,1,100),0))
setkey(d1, u, s)

# for each u, I want to lookup all their s's
us <- d1[J(u=1), "s", with=F]
# for each of the s's in the above data.table, 
#   I want to lookup other u's from the parent data.table d1

# DOESN'T WORK:
otherus <- d1[J(s = us), "u", with=F]   

# THIS WORKS but takes a really long time on my large dataset:
otherus <- merge(d1, us, by='s') 

Merge 适用于我的目的,但由于我的 'd1' >>> 'us',它需要很长时间。起初我想也许我正在使用来自基础的合并,但根据文档,它看起来像 data.table 合并被调度是类(first_arg to merge)是一个data.table。

我仍然习惯于 data.table J() 语法。有没有更好的方法来实现这一点?

提前致谢。

【问题讨论】:

  • 哎呀,这些名字令人困惑。 us 不应该指代多个u,而不是与特定u 关联的多个s?无论如何,这对我来说听起来像是图论。你在找邻居,对吧?如果是这样,您可能需要查看 igraph 包。

标签: r merge data.table lookup


【解决方案1】:

您可以为此更改密钥。

setkey(d1,s,u)

在该命令之后,相同s 值的所有u 值被组合在一起。

        u   s
   1:  20   1
   2:  35   1
   3:  36   1
   4:  87   1
   5: 123   1
  ---        
 996: 208 100
 997: 262 100
 998: 352 100
 999: 430 100
1000: 455 100

对由键列定义的组执行的操作通常运行得非常快,例如

d1[,mean(u),keyby='s']

如果您需要对us 两个组进行快速聚合,您可以存储data.table 的两个实例。一个你使用setkey(d1,u,s),另一个使用setkey(d1,s,u)。如果您想对u 的值定义的组快速执行操作,请使用前一个 data.table,否则使用后者。

【讨论】:

  • 谢谢@Georg。我实际上已经做到了——基本上是具有不同组合键的 data.table 的 2 个副本。数据集很大,我需要在 foreach 循环中执行此操作,我相信该循环会为每个“工作人员”制作一个副本,以便 RAM 快速填满。我希望有另一种解决方案。感谢收看。
  • 好吧,也许可以只存储索引列 us 以及两个 data.tables 中的行标识符以节省内存并以某种方式与 bigmemory 包结合允许将矩阵存储在共享内存中。
【解决方案2】:

以下是否有效?

d1 <- data.table(u=rep(1:500,2), s=round(runif(1000,1,100),0))
setkey(d1, u, s)
us <- d1[J(u=1), "s"]
otherus <- merge(d1, us, by='s') 

setkey(d1,s)
otherus2 <- d1[us]
identical(otherus2, otherus)

setkey(d1, u, s)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-22
    • 2013-02-12
    • 2019-12-23
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 2017-01-27
    相关资源
    最近更新 更多