我有这个data.frame
:
a b
[1,] 1 0
[2,] 2 0
[3,] 3 0
[4,] 4 0
[5,] 5 0
[6,] 6 1
[7,] 7 2
[8,] 8 3
[9,] 9 4
[10,] 10 5
我想在cumsum
上应用column a
只有当它在column b
上的相应值与0不同时才适用。
我在下面尝试了这个,但它不包括在cumsum上的起始条件:
df_cumsum <- cbind(c(1:10), c(0,0,0,0,0,1,2,3,4,5),
as.data.frame(ave(A[,1], A[,2] != 0, FUN=cumsum)))
不幸的是,我在整个专栏中获得了cumsum
:
a b c
1 1 0 1
2 2 0 3
3 3 0 6
4 4 0 10
5 5 0 15
6 6 1 6
7 7 2 13
8 8 3 21
9 9 4 30
10 10 5 40
我想获得:
a b c
1 1 0 0
2 2 0 0
3 3 0 0
4 4 0 0
5 5 0 0
6 6 1 6
7 7 2 13
8 8 3 21
9 9 4 30
10 10 5 40
感谢帮助!
最好创建索引和更新
i1 <- df1$b > 0
df1$c[i1] <- with(df1, cumsum(a[i1]))
或者在一行中
df1$c <- with(df1, cumsum(a * (b > 0)))
df1$c
#[1] 0 0 0 0 0 6 13 21 30 40
假设输入是df
,如最后的注释中可重复显示的那样,试试这个。它将a
为0的任何b
值清零。
transform(df, cum = cumsum((b > 0) * a))
赠送:
a b cum
1 1 0 0
2 2 0 0
3 3 0 0
4 4 0 0
5 5 0 0
6 6 1 6
7 7 2 13
8 8 3 21
9 9 4 30
10 10 5 40
我们假设此输入以可再现的形式显示:
Lines <- "
a b
1 0
2 0
3 0
4 0
5 0
6 1
7 2
8 3
9 4
10 5"
df <- read.table(text = Lines, header = TRUE)
a
和b
被逆转了。有固定的。
我真的很喜欢使用a * (b > 0)
的其他答案有多干净,但对于新的程序员来说,这有时会让人感到有些困惑。作为此语法的替代,您可以使用矢量化ifelse
函数。
df <- data.frame(a=c(1:10), b=c(0,0,0,0,0,1,2,3,4,5))
# One way
df$c <- cumsum(ifelse(df$b>0,df$a,0))
# Another way
df$d <- with(df,cumsum(ifelse(b>0,a,0)))