如何创建数据框每一列的累计和

How to create a cummulative sum of each column of a dataframe

我在尝试解决这个问题时遇到了一些问题。我有一个数据框 4 个变量:

rr_1 rr_2 cc_1 cc_2
 100    0     1    0
 200  100     1    1
 300  300     1    1
 400  500     1    1
   0    0     0    0

每当相应的 rr 变量的值大于 0 时,我的 cc 变量的值为 1。我想要完成的是为 cc 变量创建一个累积序列,这样最终结果应该看起来像这样:

rr_1 rr_2 cc_1 cc_2
 100    0     1    0
 200  100     2    1
 300  300     3    2
 400  500     4    3
   0    0     4    3

我已经尝试了几种方法来解决这个问题。

(1) 我创建了一个函数,例如:

df <- df1 %>% select(starts_with("cc"))
rows <- nrow(df) 

cc_cum <- function(x) {
        for(i in 2:rows) {
          df$x[i] <- df$x[i-1] + df$x[i]
        }

apply(df, 2, cc_cum)

(2) 我创建了向量:

df <- df1 %>% select(starts_with("cc"))

cc_cum <- function(x) {
          x <- as.vector(df$x)
          x <- cumsum(x)
          df$x <- x
}

apply(df, 2, cc_cum )

(3) 我也试过:

df <- df1 %>% select(starts_with("cc"))
rows <- nrow(df) 

cc_cum <- function(x) {
             for(i in 2:rows) {
                 df$x[i] <- df$x[i-1] + df$x[i]
             }
          }

apply(df, 2, cc_cum)

奇怪的是,如果我将它们从函数中删除并应用,我在上面尝试过的所有解决方案都适用于每一列。例如,此代码有效

df <- df1 %>% select(starts_with("cc"))

rows <- nrow(df) 

for(i in 2:rows) {
  df$cc_1[i] <- df$cc_1[i-1] + df$cc_1[i]
}

但是,此代码将用于具有多个 cc 级别的更大数据集,因此我无法预测会有多少,所以我无法真正编写 cc 的所有可能性。

对此的任何反馈都将非常有帮助。

将内置的 cumsum 函数用于具有 lapply

的多列
cols <- grep("^cc", names(df))
df[cols] <- lapply(df[cols], cumsum)

df
#   rr_1 rr_2 cc_1 cc_2
#1  100    0    1    0
#2  200  100    2    1
#3  300  300    3    2
#4  400  500    4    3
#5    0    0    4    3

或者使用dplyr,我们可以使用mutate_at到select特定的列

library(dplyr)
df %>%  mutate_at(vars(starts_with("cc")), cumsum)
df <-data.frame("rr_1" = c(100,200,300,400,0), "rr_2" = c(0,100,300,500,0), "cc_1" = c(1,1,1,1,0),"cc_2"=c(0,1,1,1,0))

> df
  rr_1 rr_2 cc_1 cc_2
1  100    0    1    0
2  200  100    1    1
3  300  300    1    1
4  400  500    1    1
5    0    0    0    0

csum <- function(x) cumsum(x)

new_data <- data.frame(df[c("rr_1","rr_2")],sapply(df[c("cc_1","cc_2")],csum))

> new_data
  rr_1 rr_2 cc_1 cc_2
1  100    0    1    0
2  200  100    2    1
3  300  300    3    2
4  400  500    4    3
5    0    0    4    3

带有data.table的选项。将'data.frame'转换为'data.table'(setDT(df1)),得到data.frame即startsQWith'cc'的名称,指定.SDcols ,遍历 .SD,获取 cumsum 并将输出分配 (:=) 回感兴趣的列

library(data.table)
nm1 <- names(df1)[startsWith(names(df1), "cc")]
setDT(df1)[, (nm1) := lapply(.SD, cumsum), .SDcols = nm1]
df1
#   rr_1 rr_2 cc_1 cc_2
#1:  100    0    1    0
#2:  200  100    2    1
#3:  300  300    3    2
#4:  400  500    4    3
#5:    0    0    4    3

数据

df1 <- structure(list(rr_1 = c(100L, 200L, 300L, 400L, 0L), rr_2 = c(0L, 
100L, 300L, 500L, 0L), cc_1 = c(1L, 1L, 1L, 1L, 0L), cc_2 = c(0L, 
1L, 1L, 1L, 0L)), class = "data.frame", row.names = c(NA, -5L
))