【问题标题】:Identifying group specific timed events within a defined period在定义的时间段内识别组特定的定时事件
【发布时间】: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


    【解决方案1】:

    使用最新版本(1.9.8+):

    DT[, `:=`(t1 = as.Date(t1), t2 = as.Date(t2), newvar = FALSE)]
    
    DT[DT[!is.na(zcat), .(grp, t2, t2.end = t2 + 31)],
       on = .(grp, t1 >= t2, t1 < t2.end),
       newvar := TRUE]
    

    【讨论】:

    • 我了解第 1 行,但第 2 行粗略。您是否在 DT 和包含参考日期的 DT 子集之间运行连接,其中 t2+31 作为定义我的时间间隔的 t2.end 变量。并且,如果存在匹配项,此连接会将 newvar 重置为 TRUE。此外,当我运行第 2 行时,我收到一条消息...找不到函数“。”我在 Mac/OSX 10.11.6 上运行 R3.2.2 GUI 1.66 Mavericks build (6996)。不确定这与您使用 v1.9.7+ 的注释有何关系
    • 看来你明白了。您必须拥有 data.table 1.9.7+ 版本 - 否则将无法正常工作。
    • 好的,现在使用 github 版本,需要在我的真实数据上运行它以检查一切正常和速度,非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 2017-08-29
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多