gpt4 book ai didi

r - data.table 聚合与日期滚动子集

转载 作者:行者123 更新时间:2023-12-04 09:40:40 25 4
gpt4 key购买 nike

我有一组这样的数据

d1 <- data.frame(
cat1 = sample(c('a', 'b', 'c'), 100, replace = TRUE),
date = rep(Sys.Date() - sample(1:100)),
val = rnorm(100, 50, 5)
)

require(data.table)

d2 <- data.table(d1)

我可以毫无问题地获得每日总和

d2[ , list(.N, sum(val)), by = c("cat1", "date")]

我想得到 2 天(然后是 7 天)的总和

这个有效:

d.list <- sort(unique(d2$date))
o.list <- list()

for(i in seq_along(d.list)){
o.list[[i]] <- d2[d2$date >= d.list[i] - 1 & d2$date <= d.list[i], list(.N, sum(val), max(date)), by = c("cat1")]
}

do.call(rbind, o.list)

但是在更大的数据集上会变慢,而且似乎不是 data.table 的最佳用途。

有没有更高效的方法?

最佳答案

这样会快一点:

首先我们加入精确匹配并获得最后一个索引(在多个匹配的情况下)

setkey(d2, cat1, date)
tmp1 = d2[unique(d2, by=key(d2)), which=TRUE, mult="last", allow.cartesian=TRUE]

然后,我们构造一个 d2copy 并将 date 更改为 date-1 引用。然后,我们使用 roll=-Inf 执行连接 - 这是下一个向后进行的观察。换句话说,如果没有完全匹配,它将填充下一个可用值。

d3 = copy(d2)[, date := date-1]
setkey(d3, cat1, date)
tmp2 = d2[unique(d3, by=key(d2)), roll=-Inf, which=TRUE, allow.cartesian=TRUE]

从这里开始,我们将索引放在一起:

idx1 = tmp1-tmp2+1L
idx2 = data.table:::vecseq(tmp2, idx1, sum(idx1))

idx2 的子集 d2 并从 idx1 生成唯一的 ID:

ans1 = d2[idx2][, grp := rep(seq_along(idx1), idx1)]

最后通过grp聚合得到想要的结果:

ans1 = ans1[, list(cat1=cat1[1L], date=date[.N], 
N = .N, val=sum(val)), by=grp][, grp:=NULL]
> head(ans1, 10L)
# cat1 date N val
# 1: a 2014-01-20 1 47.69178
# 2: a 2014-01-25 1 52.01006
# 3: a 2014-02-01 1 46.82132
# 4: a 2014-02-06 1 44.62404
# 5: a 2014-02-11 1 49.63218
# 6: a 2014-02-14 1 48.80676
# 7: a 2014-02-22 1 49.27800
# 8: a 2014-02-23 2 96.17617
# 9: a 2014-02-26 1 49.20623
# 10: a 2014-02-28 1 46.72708

结果与您的解决方案相同。这在我的笔记本电脑上用了 0.02 秒,而你的用了 0.58 秒。


7天,只需改变:

d3 = copy(d2)[, date := date-1]

d3 = copy(d2)[, date := date-6]

关于r - data.table 聚合与日期滚动子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23392699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com