我开始享受dplyr
,但我被困在一个用例上。我希望能够在包含数据框的每个组中应用cumsum
,但我似乎无法正确使用。
对于演示数据帧,我已生成以下数据:
set.seed(123)
len = 10
dates = as.Date('2014-01-01') + 1:len
grp_a = data.frame(dates=dates, group='A', sales=rnorm(len))
grp_b = data.frame(dates=dates, group='B', sales=rnorm(len))
grp_c = data.frame(dates=dates, group='C', sales=rnorm(len))
df = rbind(grp_a, grp_b, grp_c)
这会创建一个如下所示的数据框:
dates group sales
1 2014-01-02 A -0.56047565
2 2014-01-03 A -0.23017749
3 2014-01-04 A 1.55870831
4 2014-01-05 A 0.07050839
5 2014-01-06 A 0.12928774
6 2014-01-02 B 1.71506499
7 2014-01-03 B 0.46091621
8 2014-01-04 B -1.26506123
9 2014-01-05 B -0.68685285
10 2014-01-06 B -0.44566197
11 2014-01-02 C 1.22408180
12 2014-01-03 C 0.35981383
13 2014-01-04 C 0.40077145
14 2014-01-05 C 0.11068272
15 2014-01-06 C -0.55584113
然后我继续创建一个用于绘图的数据框,但是使用for循环,我想用更干净的东西替换。
pdf = data.frame(dates=as.Date(as.character()), group=as.character(), sales=as.numeric())
for(grp in unique(df$group)){
subs = filter(df, group == grp) %>% arrange(dates)
pdf = rbind(pdf, data.frame(dates=subs$dates, group=grp, sales=cumsum(subs$sales)))
}
我用这个pdf
来创建一个情节。
p = ggplot()
p = p + geom_line(data=pdf, aes(dates, sales, colour=group))
p + ggtitle("sales per group")
是否有更好的方法(使用dplyr方法)创建此数据帧?我已经查看了summarize
方法,但这似乎聚合了来自N个项目的一组 - > 1项。这个用例似乎打破了我的dplyr流程。有什么建议更好地接近这个吗?
答案 0 :(得分:26)
阿。摆弄后我似乎找到了它。
pdf = df %>% group_by(group) %>% arrange(dates) %>% mutate(cs = cumsum(sales))
> pdf = data.frame(dates=as.Date(as.character()), group=as.character(), sales=as.numeric())
> for(grp in unique(df$group)){
+ subs = filter(df, group == grp) %>% arrange(dates)
+ pdf = rbind(pdf, data.frame(dates=subs$dates, group=grp, sales=subs$sales, cs=cumsum(subs$sales)))
+ }
> pdf
dates group sales cs
1 2014-01-02 A -0.56047565 -0.5604756
2 2014-01-03 A -0.23017749 -0.7906531
3 2014-01-04 A 1.55870831 0.7680552
4 2014-01-05 A 0.07050839 0.8385636
5 2014-01-06 A 0.12928774 0.9678513
6 2014-01-02 B 1.71506499 1.7150650
7 2014-01-03 B 0.46091621 2.1759812
8 2014-01-04 B -1.26506123 0.9109200
9 2014-01-05 B -0.68685285 0.2240671
10 2014-01-06 B -0.44566197 -0.2215949
11 2014-01-02 C 1.22408180 1.2240818
12 2014-01-03 C 0.35981383 1.5838956
13 2014-01-04 C 0.40077145 1.9846671
14 2014-01-05 C 0.11068272 2.0953498
15 2014-01-06 C -0.55584113 1.5395087
> pdf = df %>% group_by(group) %>% mutate(cs = cumsum(sales))
> pdf
Source: local data frame [15 x 4]
Groups: group
dates group sales cs
1 2014-01-02 A -0.56047565 -0.5604756
2 2014-01-03 A -0.23017749 -0.7906531
3 2014-01-04 A 1.55870831 0.7680552
4 2014-01-05 A 0.07050839 0.8385636
5 2014-01-06 A 0.12928774 0.9678513
6 2014-01-02 B 1.71506499 1.7150650
7 2014-01-03 B 0.46091621 2.1759812
8 2014-01-04 B -1.26506123 0.9109200
9 2014-01-05 B -0.68685285 0.2240671
10 2014-01-06 B -0.44566197 -0.2215949
11 2014-01-02 C 1.22408180 1.2240818
12 2014-01-03 C 0.35981383 1.5838956
13 2014-01-04 C 0.40077145 1.9846671
14 2014-01-05 C 0.11068272 2.0953498
15 2014-01-06 C -0.55584113 1.5395087
答案 1 :(得分:1)
尝试使用
group_by(group) %>%
arrange(group) %>%
summarise(cs = sum(sales)) %>%
mutate(sales_grp = cumsum(cs))
我知道这个问/答有点过时,但这可能会帮助任何人在阅读dplyr发布的cumsum()解决方案后陷入困境 在https://dplyr.tidyverse.org/articles/window-functions.html。和http://www.sthda.com/english/articles/17-tips-tricks/57-dplyr-how-to-add-cumulative-sums-by-groups-into-a-data-framee/
以上链接中发布的解决方案未按组进行汇总。该代码仅按顺序添加下一行-不是分组的累加总和。我认为OP正在寻找A组,B组和C组的销售总额,每个组的总和加到下一个-在OP的情况下,您的总n()应该是3,而不是15,并且有一个分组的总和()。例如,如果您要计算到10月底您的年度销售额百分比,那么这将很有帮助,例如,您希望按月计算的销售额之和,然后按年份计算其总额。>
因此,您需要首先按每个组汇总值,然后按组顺序对其进行汇总。 PS-这是我第一次尝试回答关于SO的问题并发布对我有用的解决方案的尝试;因此,如果我的回答有误,希望您能好一些。我总是尝试从错误中学习。