首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据日期计算数据表中以前的行

根据日期计算数据表中以前的行
EN

Stack Overflow用户
提问于 2016-03-01 14:40:47
回答 1查看 607关注 0票数 5

(很抱歉,如果这里的一些术语过时了--我来自SQL背景,而我只是进入R世界)

我有一个数据表,其中包含一系列按日期排序的条目。数据表中的一个字段是一个分组值,另一个是时间值。使用按组排序的数据(或键控--我对R不熟悉,并且仍然不确定差异),我希望在给定的时间范围内,对该组中的每一行在当前行(包括当前行)前面的几行进行计数。

下面是我尝试使用Loblolly数据集的一个简化示例:

准备示例数据:

代码语言:javascript
复制
library(lubridate)
library(zoo)
library(data.table)
DT = as.data.table(Loblolly)
DT[,rd := Sys.time() + years(age)]
setkey(DT,Seed,rd)

现在,我们有了一个按Seed (组)和rd (my列)排序的数据表。我有一个基于10年间隔的计算值(ct)的解决方案:

代码语言:javascript
复制
DT[,.ct:=mapply(function(x,y) DT[(rd>x-years(10) & rd<=x &Seed==y),.N],DT$rd,DT$Seed)]

这将在此示例数据集中产生所需的结果:

代码语言:javascript
复制
    height age Seed                  rd  ct
 1:   3.93   3  329 2019-03-01 13:38:00   1
 2:   9.34   5  329 2021-03-01 13:38:00   2
 3:  26.08  10  329 2026-03-01 13:38:00   3
 4:  37.79  15  329 2031-03-01 13:38:00   2
 5:  48.31  20  329 2036-03-01 13:38:00   2
 6:  56.43  25  329 2041-03-01 13:38:00   2
 7:   4.12   3  327 2019-03-01 13:38:00   1
 8:   9.92   5  327 2021-03-01 13:38:00   2
 9:  26.54  10  327 2026-03-01 13:38:00   3
10:  37.82  15  327 2031-03-01 13:38:00   2
...
...

然而,我需要扩大这一规模,在超过500万的记录上工作,跨越大约10,000组,而且要花很长的时间才能在那里运行。有没有一种更快、更少笨拙的方法来做我想做的事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-01 21:05:39

下面是使用data.table::foverlaps的一个可能的解决方案。这里的想法是首先加入整个范围的{Sys.time() - years(10), Sys.time() + years(age)}。然后,只计算差异小于<= 10年的实例。

代码语言:javascript
复制
DT <- as.data.table(Loblolly)
DT[, c("rd", "rd2") := Sys.time() + years(age)] # create identical columns so foverlaps will work
setkey(DT, Seed, rd, rd2) # key by all for same reason
DT2 <- DT[, .(Seed, rd = rd - years(10), rd2, indx = .I)] # create minum range, create index to store row number
DT[, ct := foverlaps(DT, DT2)[i.rd > rd, .N, by = indx]$N] # run foverlaps, subset by condition and count
head(DT, 10)
#     height age Seed                  rd                 rd2 ct
#  1:   3.93   3  329 2019-03-01 22:59:02 2019-03-01 22:59:02  1
#  2:   9.34   5  329 2021-03-01 22:59:02 2021-03-01 22:59:02  2
#  3:  26.08  10  329 2026-03-01 22:59:02 2026-03-01 22:59:02  3
#  4:  37.79  15  329 2031-03-01 22:59:02 2031-03-01 22:59:02  2
#  5:  48.31  20  329 2036-03-01 22:59:02 2036-03-01 22:59:02  2
#  6:  56.43  25  329 2041-03-01 22:59:02 2041-03-01 22:59:02  2
#  7:   4.12   3  327 2019-03-01 22:59:02 2019-03-01 22:59:02  1
#  8:   9.92   5  327 2021-03-01 22:59:02 2021-03-01 22:59:02  2
#  9:  26.54  10  327 2026-03-01 22:59:02 2026-03-01 22:59:02  3
# 10:  37.82  15  327 2031-03-01 22:59:02 2031-03-01 22:59:02  2

编辑17/3/2017:

使用data.table v1.10.4+,您现在可以将非uqui联接与by = .EACHI结合使用。这基本上允许您使用>=<=来连接,而不仅仅是精确的连接,还可以在连接时运行计算(以避免笛卡尔连接,就像在您的例子中那样),并且只返回最后的结果。所以在你的具体情况下你可以

代码语言:javascript
复制
DT[, rd10 := rd - years(10)]
DT[, ct := DT[DT, .N, on = .(Seed, rd <= rd, rd > rd10), by = .EACHI]$N]
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35725815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档