Суммирование строк на основе критериев в R - PullRequest
0 голосов
/ 09 июля 2020

У меня есть df, где столбец A - это уникальный идентификатор, B - фактически совокупная группировка, всегда начиная с 0, C - это итог. Хотите, чтобы в столбце D была совокупная сумма C на основе B.

, например, начните с:

A = 1:20
B = c(0,1,2,3,4,0,1,0,1,2,3,4,5,6,7,8,0,1,2,3)
C = c(0,4,1,7,0,1,2,5,4,3,2,1,4,8,7,2,1,2,3,4)
test = data.frame(A, B, C)

test df:

    A B C
1   1 0 0
2   2 1 4
3   3 2 1
4   4 3 7
5   5 4 0
6   6 0 1
7   7 1 2
8   8 0 5
9   9 1 4
10 10 2 3
11 11 3 2
12 12 4 1
13 13 5 4
14 14 6 8
15 15 7 7
16 16 8 2
17 17 0 1
18 18 1 2
19 19 2 3
20 20 3 4

Хотите получить общую столбец для отображения:

    A B C total
1   1 0 0     0
2   2 1 4     4
3   3 2 1     5
4   4 3 7    12
5   5 4 0    12
6   6 0 1     1
7   7 1 2     3
8   8 0 5     5
9   9 1 4     9
10 10 2 3    12
11 11 3 2    14
12 12 4 1    15
13 13 5 4    19
14 14 6 8    27
15 15 7 7    34
16 16 8 2    36
17 17 0 1     1
18 18 1 2     3
19 19 2 3     6
20 20 3 4    10

Я пробовал различные циклы for и while, но не могу заставить его работать:

test$total <- 0
for (i in test$A) {
  if(test$B == 0) {
    test$total <- test$B
  } else {
    test[i,4] <- test[i,3] + test[(i-1), 2]   
  }
}

Ответы [ 3 ]

1 голос
/ 09 июля 2020

Вижу, принятый ответ уже есть. Я просто хотел показать, что это можно сделать относительно легко в Base-R.

test$total <- unlist(tapply(test$C,cumsum(test$B==0),cumsum))

    A B C total
1   1 0 0     0
2   2 1 4     4
3   3 2 1     5
4   4 3 7    12
5   5 4 0    12
6   6 0 1     1
7   7 1 2     3
8   8 0 5     5
9   9 1 4     9
10 10 2 3    12
11 11 3 2    14
12 12 4 1    15
13 13 5 4    19
14 14 6 8    27
15 15 7 7    34
16 16 8 2    36
17 17 0 1     1
18 18 1 2     3
19 19 2 3     6
20 20 3 4    10
1 голос
/ 09 июля 2020

Вы можете использовать dplyr:

test %>%
  group_by(id=cumsum(B==0)) %>%
  mutate(D = cumsum(C)) %>%
  ungroup %>%
  select(-id)

возвращает

# A tibble: 20 x 4
       A     B     C     D
   <int> <dbl> <dbl> <dbl>
 1     1     0     0     0
 2     2     1     4     4
 3     3     2     1     5
 4     4     3     7    12
 5     5     4     0    12
 6     6     0     1     1
 7     7     1     2     3
 8     8     0     5     5
 9     9     1     4     9
10    10     2     3    12
11    11     3     2    14
12    12     4     1    15
13    13     5     4    19
14    14     6     8    27
15    15     7     7    34
16    16     8     2    36
17    17     0     1     1
18    18     1     2     3
19    19     2     3     6
20    20     3     4    10
0 голосов
/ 09 июля 2020

Вы можете попробовать это:

library(zoo)
library(dplyr)

#Data

DF <- structure(list(V1 = 1:20, A = 1:20, B = c(0L, 1L, 2L, 3L, 4L, 
0L, 1L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 0L, 1L, 2L, 3L), 
    C = c(0L, 4L, 1L, 7L, 0L, 1L, 2L, 5L, 4L, 3L, 2L, 1L, 4L, 
    8L, 7L, 2L, 1L, 2L, 3L, 4L)), class = "data.frame", row.names = c(NA, 
-20L))
#Create index
index <- which(DF$B==0)
#Create val
val <- letters[1:length(index)]
#Create empty var
DF$I <- NA
#Assign
DF$I[index]<-val
#Fill
DF$I <- na.locf(DF$I)
#Mutate
DF %>% group_by(I) %>% mutate(D=cumsum(C)) %>% ungroup() %>% select(-4) -> DF1


# A tibble: 20 x 4
       A     B     C     D
   <int> <int> <int> <int>
 1     1     0     0     0
 2     2     1     4     4
 3     3     2     1     5
 4     4     3     7    12
 5     5     4     0    12
 6     6     0     1     1
 7     7     1     2     3
 8     8     0     5     5
 9     9     1     4     9
10    10     2     3    12
11    11     3     2    14
12    12     4     1    15
13    13     5     4    19
14    14     6     8    27
15    15     7     7    34
16    16     8     2    36
17    17     0     1     1
18    18     1     2     3
19    19     2     3     6
20    20     3     4    10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...