提问人:Rock 提问时间:5/31/2013 最后编辑:HenrikRock 更新时间:6/5/2022 访问量:61230
按组计算累积总和 (cumsum)
Calculate cumulative sum (cumsum) by group
问:
使用数据框:
df <- data.frame(id = rep(1:3, each = 5)
, hour = rep(1:5, 3)
, value = sample(1:15))
我想添加一个与以下列匹配的累积总和列:id
df
id hour value csum
1 1 1 7 7
2 1 2 9 16
3 1 3 15 31
4 1 4 11 42
5 1 5 14 56
6 2 1 10 10
7 2 2 2 12
8 2 3 5 17
9 2 4 6 23
10 2 5 4 27
11 3 1 1 1
12 3 2 13 14
13 3 3 8 22
14 3 4 3 25
15 3 5 12 37
我怎样才能有效地做到这一点?谢谢!
答:
65赞
IRTFM
5/31/2013
#1
df$csum <- ave(df$value, df$id, FUN=cumsum)
ave
如果您想要一个与现有向量长度相等的按组向量,则是“首选”函数,并且可以仅从这些子向量计算。如果需要基于多个“并行”值进行分组处理,则基本策略是 。do.call(rbind, by(dfrm, grp, FUN))
评论
0赞
Rock
5/31/2013
unique.default(x, nmax = nmax) 中的错误:unique() 仅适用于向量
1赞
IRTFM
5/31/2013
我一直忘记......需要命名 FUN 参数。
4赞
Brian D
11/19/2016
请注意,如果多个列定义每个唯一行,则可以添加其他变量。例如,.id
df$csum <- ave(df$value, df$id1, df$id2, FUN=cumsum)
0赞
smci
8/30/2019
@42- 自 2013 年起被封存(已经六年前)。你应该推荐 /tidyverse/plyr
dplyr
data.table
1赞
IRTFM
8/30/2019
我没有说我不喜欢.我说我在现在删除的评论中提到了它。我投票支持A5C1D2H2I1M1N2O1R2T1的解决方案,我承认这是非常清楚的data.table
8赞
Didzis Elferts
5/31/2013
#2
使用库 .plyr
library(plyr)
ddply(df,.(id),transform,csum=cumsum(value))
30赞
A5C1D2H2I1M1N2O1R2T1
5/31/2013
#3
为了添加到替代方案中,的语法很好:data.table
library(data.table)
DT <- data.table(df, key = "id")
DT[, csum := cumsum(value), by = key(DT)]
或者,更紧凑地说:
library(data.table)
setDT(df)[, csum := cumsum(value), id][]
以上将:
- 通过引用将 转换为
data.frame
data.table
- 计算按 id 分组的值的累积总和,并按引用进行分配
- 打印(最后一个)整个操作的结果
[]
“df”现在将是一个带有“csum”列的 a。data.table
27赞
tjebo
11/13/2017
#4
使用 dplyr::
require(dplyr)
df %>% group_by(id) %>% mutate(csum = cumsum(value))
评论
3赞
Kathiravan Meeran
11/15/2018
嘿,我试过你的方法。不知何故,分组无法正常工作。它对所有数据点进行 cumsum 而不进行分组。有什么建议吗?
0赞
tjebo
11/15/2018
有时,在这些情况下,启动新的 R 会话会有所帮助。在示例数据上尝试我的代码。
3赞
user3602585
4/10/2019
只是一个更新,您可能有一个已加载的包。显式引用也将修复它: ''' df %>% group_by(id) %>% dplyr::mutate(csum = cumsum(value)) '''plyr
dplyr
0赞
Ben
6/30/2023
我对 dplyr 的明确引用并没有产生准确的分组结果;使用 DIDave()
2赞
Mohamed Desouky
6/5/2022
#5
使用基本 R
df <- data.frame(id = rep(1:3, each = 5)
, hour = rep(1:5, 3)
, value = sample(1:15))
transform(df , csum = ave(value , id , FUN = cumsum))
#> id hour value csum
#> 1 1 1 4 4
#> 2 1 2 12 16
#> 3 1 3 13 29
#> 4 1 4 6 35
#> 5 1 5 5 40
#> 6 2 1 15 15
#> 7 2 2 1 16
#> 8 2 3 2 18
#> 9 2 4 8 26
#> 10 2 5 9 35
#> 11 3 1 11 11
#> 12 3 2 7 18
#> 13 3 3 10 28
#> 14 3 4 3 31
#> 15 3 5 14 45
由 reprex 软件包 (v2.0.1) 于 2022-06-05 创建
评论