给定一个 data.table
带三个字段 member_id
, provider_id
和 srvc_dt
.我需要计算一对提供者看到的不同成员的数量。如果访问发生在 180 天内,则成员被称为访问了两个提供商。这用于使用#visits 的阈值构建无向图并查找连接组件。
我正在使用 Cartesian product with filter data.table 中建议的方法.
我需要运行的实例有超过 300 万条记录,运行时间超过 5 分钟。有没有重写的方法或新的 data.table 函数,以便它运行得更快?
require(data.table)
nmem <- 5000
data.dt <- data.table(member_id=sample(10000:1000000,nmem,replace=TRUE), provider_id=sample(1000:2000,nmem,replace=TRUE),
srvc_dt=sample(seq(as.Date('2014/01/01'), as.Date('2015/01/01'), by="day"), nmem, replace=TRUE))
setkey(data.dt, member_id)
prov_pair.dt <- data.dt[data.dt, {
idx = provider_id<i.provider_id & abs(srvc_dt-i.srvc_dt)<180
list(provider_id1 = provider_id[idx],
srvc_dt1 = srvc_dt[idx],
provider_id2 = i.provider_id[any(idx)],
srvc_dt2 = i.srvc_dt[any(idx)]
)
}, by=.EACHI, allow=TRUE]
prov_pair_agg.dt <- prov_pair.dt[, .(weight=length(unique(member_id))), .(provider_id1,provider_id2)]
最佳答案
简单的左连接然后过滤:
prov_pair.dt <- data.dt[data.dt,allow.cartesian=T][provider_id<i.provider_id &
abs(srvc_dt-i.srvc_dt)<180,]
provider_id<i.provider_id
防止重复计算对 x,y 和 y,x 的相同访问。另外,现在使用
provider_id
和 i.provider_id
而不是 provider_id1
和 provider_id2
在计算 prov_pair_agg.dt
:prov_pair_agg.dt <- prov_pair.dt[, .(weight=length(unique(member_id))),
.(provider_id,i.provider_id)]
在 nmem=1,000,000 的 16GB 内存机器上,按照您当前的方法,这需要 1.487s 与 106.034s。
关于r - 通过过滤加速 data.table 笛卡尔积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37107132/