我想对字段进行累积求和,但只要遇到0就重置聚合值.
这是我想要的一个例子:
data.frame(campaign = letters[1:4] ,
date=c("jan","feb","march","april"),
b = c(1,0,1,1) ,
whatiwant = c(1,0,1,2)
)
campaign date b whatiwant
1 a jan 1 1
2 b feb 0 0
3 c march 1 1
4 d april 1 2
Run Code Online (Sandbox Code Playgroud)
Dav*_*urg 15
另一个基础就是
with(df, ave(b, cumsum(b == 0), FUN = cumsum))
## [1] 1 0 1 2
Run Code Online (Sandbox Code Playgroud)
这将b根据0外观将列分组,并计算b每个组的累积总和
使用最新data.table版本的另一种解决方案(v 1.9.6+)
library(data.table) ## v 1.9.6+
setDT(df)[, whatiwant := cumsum(b), by = rleid(b == 0L)]
# campaign date b whatiwant
# 1: a jan 1 1
# 2: b feb 0 0
# 3: c march 1 1
# 4: d april 1 2
Run Code Online (Sandbox Code Playgroud)
每条评论都有一些基准
set.seed(123)
x <- sample(0:1e3, 1e7, replace = TRUE)
system.time(res1 <- ave(x, cumsum(x == 0), FUN = cumsum))
# user system elapsed
# 1.54 0.24 1.81
system.time(res2 <- Reduce(function(x, y) if (y == 0) 0 else x+y, x, accumulate=TRUE))
# user system elapsed
# 33.94 0.39 34.85
library(data.table)
system.time(res3 <- data.table(x)[, whatiwant := cumsum(x), by = rleid(x == 0L)])
# user system elapsed
# 0.20 0.00 0.21
identical(res1, as.integer(res2))
## [1] TRUE
identical(res1, res3$whatiwant)
## [1] TRUE
Run Code Online (Sandbox Code Playgroud)
另一个迟到的想法
ff = function(x)
{
cs = cumsum(x)
cs - cummax((x == 0) * cs)
}
ff(c(0, 1, 3, 0, 0, 5, 2))
#[1] 0 1 4 0 0 5 7
Run Code Online (Sandbox Code Playgroud)
并比较:
library(data.table)
ffdt = function(x)
data.table(x)[, whatiwant := cumsum(x), by = rleid(x == 0L)]$whatiwant
x = as.numeric(x) ##because 'cumsum' causes integer overflow
identical(ff(x), ffdt(x))
#[1] TRUE
microbenchmark::microbenchmark(ff(x), ffdt(x), times = 25)
#Unit: milliseconds
# expr min lq median uq max neval
# ff(x) 315.8010 362.1089 372.1273 386.3892 405.5218 25
# ffdt(x) 374.6315 407.2754 417.6675 447.8305 534.8153 25
Run Code Online (Sandbox Code Playgroud)
您可以将该Reduce函数与自定义函数一起使用,当遇到的新值为0时返回0,否则将新值添加到累计值:
Reduce(function(x, y) if (y == 0) 0 else x+y, c(1, 0, 1, 1), accumulate=TRUE)
# [1] 1 0 1 2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2549 次 |
| 最近记录: |