【发布时间】:2017-02-27 21:44:14
【问题描述】:
我有一个记录分类事件的数据集,其中有两个时间点 t1 和 t2,其中 t2 离开 >= t1。事件分类为 z1、z2、z3 或 NA(未分类)。对于每个组(grp),我想识别 t1 在组中任何分类的 t2 事件的指定时间段内的事件。在我的示例中,我将这些 t2 事件称为参考日期。循环过程显示了我需要的内容,但在大型数据集上效率极低。我要求它在包含数百万行和超过一百万组的数据集上运行。
我还展示了我使用 data.table 语法更有效地编写代码的尝试。我的方法是将每个组的参考日期集分配给向量“ref”,然后为组中的每一行计算 t1 和参考日期之间的差异,并根据指定的时间间隔测试这些时间间隔,然后返回一个布尔值,指示特定行 t1 是否在任何参考日期的 30 天内。当我将每个组限制为单个参考日期(通过获取第一个日期 [1])时,代码可以工作,但是当我根据需要允许多个参考日期时,代码会返回错误。显然我不明白 j 语句中的数据表在做什么。有人可以解释我的错误并提出一个有效的 data.table 解决方案。
示例数据
library("data.table")
DT <-read.table(text=
"grp,zcat,t1,t2
a,NA,2007-03-18,2007-03-28
a,z1,2007-08-04,2007-08-14
a,NA,2007-08-21,2007-08-23
a,NA,2007-11-21,2007-11-29
a,z1,2007-12-10,2007-12-13
a,z2,2008-02-16,2008-02-19
a,NA,2008-03-14,2008-03-21
a,NA,2008-05-27,2008-06-03
b,NA,2003-04-22,2003-04-27
b,z3,2003-05-11,2003-05-23
b,z1,2003-07-16,2003-08-02
c,z3,2011-01-18,2011-02-07
c,z3,2011-03-01,2011-03-13
c,NA,2011-03-30,2011-04-11
c,NA,2011-05-21,2011-05-28",
header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings="NA", colClasses="character")
DT <-data.table(DT)
setorder(DT,grp,t1)
分组参考日期
grp-a: "2007-08-14" "2007-12-13" "2008-02-19"
grp-b: "2003-05-23" "2003-08-02"
grp-c: "2011-02-07" "2011-03-13"
循环程序 - 好的
out<-c()
for(i in 1:nrow(DT)){
ref <-DT[grp == grp[i] & !is.na(zcat),t2]
temp <-as.Date(DT$t1[i]) - as.Date(ref)
out[i] <-any(temp >=0 & temp <31)
rm(ref,temp)
# ref; delta; delta >=0 & delta <31
if(i==nrow(DT)){DT[, newvar :=out]; rm(out)}
}
data.table 编码尝试
前两个示例工作正常,但每个组使用一个参考数据,第三个示例对所有参考日期使用相同的原则,但失败了。问题似乎在于 j 语句如何处理多个区间值
DT[,{ref=t2[!is.na(zcat)]; delta=as.Date(t1) - as.Date(ref)[1]; delta >0 & delta <30}, by=grp]
DT[,{ref=t2[!is.na(zcat)][1]; delta=as.Date(t1) - as.Date(ref); delta >0 & delta <30}, by=grp]
DT[,{ref=t2[!is.na(zcat)]; delta=as.Date(t1) - as.Date(ref); any(delta >0 & delta <30)}, by=grp]
【问题讨论】:
标签: r data.table data-analysis