Делать накопительные суммы по нескольким переменным в dplyr - PullRequest
0 голосов
/ 30 мая 2019

Мои данные выглядят так:

library(tidyverse)
Date <- c(rep("5/22/19", 3), rep("5/23/19", 3), rep("5/24/19", 3))
Source <- rep(c("Control", "A", "B"), 3)
ValueA <- c(12080, 12012, 11944, 13345, 13342, 13422, 16226, 16045, 16221)
ValueB <- c(11, 9, 13, 11, 9, 7, 12, 9, 15)
df <- tibble(Date, Source, ValueA, ValueB)

df
# A tibble: 9 x 4
  Date    Source  ValueA ValueB
  <chr>   <chr>    <dbl>  <dbl>
1 5/22/19 Control  12080     11
2 5/22/19 A        12012      9
3 5/22/19 B        11944     13
4 5/23/19 Control  13345     11
5 5/23/19 A        13342      9
6 5/23/19 B        13422      7
7 5/24/19 Control  16226     12
8 5/24/19 A        16045      9
9 5/24/19 B        16221     15

То, что я хочу, это кумулятивные суммы как Date , так и Source. Таким образом, результат будет выглядеть так:

  Date    Source  ValueA ValueB
1 5/22/19 Control  12080     11
2 5/22/19 A        12012      9
3 5/22/19 B        11944     13
4 5/23/19 Control  25425     22
5 5/23/19 A        25354     18
6 5/23/19 B        25366     20
7 5/24/19 Control  41651     34
8 5/24/19 A        41399     27
9 5/24/19 B        41587     35

Однако, когда я использую этот код:

df <- df %>%
  group_by(Date, Source) %>%
  summarize(
    ValueA = sum(ValueA, na.rm = TRUE),
    ValueB = sum(ValueB, na.rm = TRUE),
    Cum_A = cumsum(ValueA, na.rm = TRUE),
    Cum_B = cumsum(ValueB, na.rm = TRUE)
  )

Я получаю ошибку

Error in cumsum(ValueA, na.rm = TRUE) : 
  2 arguments passed to 'cumsum' which requires 1

Я предполагаю, что функция cumsum не предназначена для обработки нескольких группирующих переменных. Так как же получить желаемый результат?

1 Ответ

1 голос
/ 31 мая 2019

Я думаю, вам просто нужно использовать group_by(Source). Посмотрите, делает ли это то, что вы ищете.

Некоторые заметки:

  • Необязательно хранить Source в arrange(); удаление приведет к воссозданию данных, которые вы просили Я включил его, чтобы результат cumsum() был более очевидным
  • Учитывая ваш текущий набор данных (без дубликатов Source или Date), агрегация не требуется, и mutate() сделает свое дело
  • cumsum() не принимает аргумент na.rm, но вы можете заменить 0 на replace_na()
df <- 
  tibble(
    Date = rep(c("5/22/19", "5/23/19", "5/24/19"), each = 3),
    Source = rep(c("Control", "A", "B"), 3), 
    ValueA = c(12080, 12012, 11944, 13345, 13342, 13422, 16226, 16045, 16221), 
    ValueB = c(11, 9, 13, NA, 9, 7, 12, 9, 15)
  )


df %>%  
  arrange(Source, Date) %>% 
  group_by(Source) %>%
  mutate(
    Cum_A = cumsum(replace_na(ValueA, 0)),
    Cum_B = cumsum(replace_na(ValueB, 0))
  ) %>% 
  ungroup()

# Date    Source  ValueA ValueB Cum_A Cum_B
# 5/22/19 A        12012      9 12012     9
# 5/23/19 A        13342      9 25354    18
# 5/24/19 A        16045      9 41399    27
# -----------------------------------------
# 5/22/19 B        11944     13 11944    13
# 5/23/19 B        13422      7 25366    20
# 5/24/19 B        16221     15 41587    35
# -----------------------------------------
# 5/22/19 Control  12080     11 12080    11
# 5/23/19 Control  13345     NA 25425    11
# 5/24/19 Control  16226     12 41651    34
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...