R- 在 cumsum 函数中包含起点
R- Include starting point in cumsum function
我有这个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
我想在 column a
上应用 cumsum
仅当其在 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
,如末尾的注释中所示,试试这个。它会将 b
为 0 的任何 a
值清零。
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)))
我有这个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
我想在 column a
上应用 cumsum
仅当其在 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
,如末尾的注释中所示,试试这个。它会将 b
为 0 的任何 a
值清零。
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)))