R- Включить начальную точку в функцию cumsum - PullRequest
1 голос
/ 11 марта 2019

У меня есть 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

Спасибо за помощь!

Ответы [ 3 ]

3 голосов
/ 11 марта 2019

Предполагая, что ввод df, как воспроизводимо показано в примечании в конце, попробуйте это. Обнуляет любое значение a, для которого b равно 0.

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 были полностью изменены. Исправили.

1 голос
/ 11 марта 2019

Было бы лучше создать индекс и обновить

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
0 голосов
/ 11 марта 2019

Мне действительно нравится, как другие ответы используют 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)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...