如何创建数据框每一列的累计和
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
))
我在尝试解决这个问题时遇到了一些问题。我有一个数据框 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
))