首页 > 解决方案 > 如何使用特定的列顺序计算累积和?

问题描述

我有一个数据集,我想在其中计算 R 中的累积总和。我的数据名称示例agfield

ID 仰卧起坐 兰德
1 500 1
2 5681 4
3 6514 3
4 25 2
... ... ...

基本上,我想使用 RAND 列的顺序计算 csum 列中 SUP 列的累积和。预期结果:

ID 仰卧起坐 兰德 csum
1 500 1 500
2 5681 4 12720
3 6514 3 7039
4 25 2 525
... ... ... ...

我在这里查看了有关此主题的其他几个问题/答案,但我可以得到遵循 RAND 列顺序的结果。我尝试使用 agfield$csum<-ave(agfield$SUP, agfield$RAND, FUN=cumsum),但它只给了我 SUP 号码并且不做累计和。我也尝试使用 group_by,但它做了同样的事情。您对执行此操作的有效方法有什么建议吗?

标签: rdataframeaggregate

解决方案


1) order使用最后注释中的数据并假设您想在不更改行顺序的情况下执行此操作,此基本解决方案定义了排序SUP为的排列,将o其应用于SUPcumsum然后返回通过应用逆序,即order(o).

o <- order(agfield$RAND)
transform(agfield, cum = cumsum(SUP[o])[order(o)])

给予:

  ID  SUP RAND  csum
1  1  500    1   500
2  2 5681    4 12720
3  3 6514    3  7039
4  3   25    1   525

这是一个演示,表明逆序确实是上面显示的表达式。

set.seed(123)
x <- rnorm(1000)
o <- order(x)
identical(x, x[o][order(o)])
## [1] TRUE

如果对数据框进行排序是可以接受的,那么我们可以这样做,这会稍微短一些。

o <- order(agfield$RAND)
transform(agfield[o, ], cum = cumsum(SUP))

2) sql SQL 具有特定功能,允许以不同于输入的顺序获取累积总和,因此我们可以执行以下操作。请注意,除非我们明确要求,否则 SQL 不保证表的顺序,因此我们order by rowid在最后使用以确保返回原始顺序——如果返回的顺序不重要,则可以省略它。

library(sqldf)
sqldf("select ID, SUP, RAND, sum(SUP) over (order by RAND, rowid) csum 
  from agfield
  order by rowid")

给予:

  ID  SUP RAND  csum
1  1  500    1   500
2  2 5681    4 12720
3  3 6514    3  7039
4  3   25    1   525

笔记

Lines <- "
ID SUP RAND
1 500 1
2 5681 4
3 6514 3
3 25 1"
agfield <- read.table(text = Lines, header = TRUE)

推荐阅读