Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 基于日期计算数据表中的前几行_R_Data.table_Zoo - Fatal编程技术网

R 基于日期计算数据表中的前几行

R 基于日期计算数据表中的前几行,r,data.table,zoo,R,Data.table,Zoo,(如果这里的一些术语不适用,我深表歉意-我来自SQL背景,我刚刚进入R世界) 我有一个数据表,其中有一系列按日期排序的条目。数据表中的一个字段是分组值,另一个字段是时间值。 在数据按组排序(或键入-我对R是新手,但仍然不确定差异)然后按日期排序的情况下,我想在给定的时间跨度内,为每一行计算该组中在当前行(包括当前行)之前的行数 下面是我尝试使用Loblolly数据集执行的一个简化示例: 准备示例数据: library(lubridate) library(zoo) library(data.ta

(如果这里的一些术语不适用,我深表歉意-我来自SQL背景,我刚刚进入R世界)

我有一个数据表,其中有一系列按日期排序的条目。数据表中的一个字段是分组值,另一个字段是时间值。 在数据按组排序(或键入-我对R是新手,但仍然不确定差异)然后按日期排序的情况下,我想在给定的时间跨度内,为每一行计算该组中在当前行(包括当前行)之前的行数

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

准备示例数据:

library(lubridate)
library(zoo)
library(data.table)
DT = as.data.table(Loblolly)
DT[,rd := Sys.time() + years(age)]
setkey(DT,Seed,rd)
现在我们有了一个按Seed(组)和rd(我的日期列)排序的数据表。我有一个解决方案,它将根据10年的间隔产生我的计数值(ct):

DT[,.ct:=mapply(function(x,y) DT[(rd>x-years(10) & rd<=x &Seed==y),.N],DT$rd,DT$Seed)]

然而,我需要扩大规模,在大约10000个组中处理500万条以上的记录,而且要运行很长时间,这是不可行的。有没有一种更快、更简单的方法来完成我想做的事情?

这里有一个可能的解决方案,使用
数据。table::foverlaps
。这里的想法是首先加入整个
{Sys.time()-years(10),Sys.time()+years(age)}
。然后,当差异较小时,只计算实例。这在大约100000行时非常有效,但在100万行时,内存使用率会迅速膨胀(工作集为14GB)-我假设是因为R在foverlaps期间创建了一个非常大的中间数据结构。有没有办法避免这种情况?有没有可能以某种方式绕过这些小组?是的,我很害怕。。。这是因为我做了一个完整的连接。我想对于这个解决方案,您需要一个大RAM,或者等待其他人提供更好的解决方案。我已经用一个更现代的解决方案更新了答案。我认为现在它应该更快,内存效率更高。请使用最新的data.table版本进行尝试。
    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
...
...
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
DT[, rd10 := rd - years(10)]
DT[, ct := DT[DT, .N, on = .(Seed, rd <= rd, rd > rd10), by = .EACHI]$N]