我想在数据框中添加一个列,如果另一个变量对于两行相等,则会产生另一个变量的累计和。例如:
Row Var1 Var2 CumVal
1 A 2 2
2 A 4 6
3 B 5 5
所以我希望CumVal
累积/求和Var2
列,如果第2行的Var1
obs等于第1行Var1
,则换句话说,如果是等于之前的obs。
答案 0 :(得分:1)
如果cumsum
基于Var1
作为分组变量
library(dplyr)
df %>%
group_by(Var1) %>%
mutate(CumVal=cumsum(Var2))
或者
library(data.table)
setDT(df)[, CumVal:=cumsum(Var2), by=Var1]
或使用base R
transform(df, CumVal=ave(Var2, Var1, FUN=cumsum))
如果是基于相邻元素是否不相等
transform(df, CumVal= ave(Var2, cumsum(c(TRUE,Var1[-1]!=
Var1[-nrow(df)])), FUN=cumsum))
# Row Var1 Var2 CumVal
#1 1 A 2 2
#2 2 A 4 6
#3 3 B 5 5
#4 4 A 6 6
或dplyr
方法
df %>%
group_by(indx= cumsum(c(TRUE,(lag(Var1)!=Var1)[-1]))) %>%
mutate(CumVal=cumsum(Var2)) %>%
ungroup() %>%
select(-indx)
df <- structure(list(Row = 1:4, Var1 = c("A", "A", "B", "A"), Var2 = c(2L,
4L, 5L, 6L)), .Names = c("Row", "Var1", "Var2"), class = "data.frame",
row.names = c(NA, -4L))
答案 1 :(得分:0)
我喜欢rle
,它会检测向量中的类似连续值并以合成的方式描述它。例如。我们说我们有一个长度为10的向量x
:
x <- c(2, 3, 2, 2, 2, 2, 0, 0, 2, 1)
rle
能够检测到有4个连续的2和2个连续的0:
rle(x)
# Run Length Encoding
# lengths: int [1:6] 1 1 4 2 1 1
# values : num [1:6] 2 3 2 0 2 1
(在输出中,我们可以有2个长度不同于1对应于值4和2)
我们可以使用此函数将cumsum
应用于另一个向量的子向量。我们假设我们要在新的向量cumcum
上应用y <- 1:10
,但仅适用于x
的重复值(将存储在因子f
中) :
y <- 1:10
z <- rle(x)$lengths
f <- factor(rep( seq_along(z), z) )
然后,我们可以使用by
或tapply
(或其他内容来实现所需的输出):
cumval <- unlist(tapply(y, f, cumsum))