Как объединить два наблюдения в группе в новое наблюдение с помощью dplyr - PullRequest
1 голос
/ 26 сентября 2019

У меня есть следующий кадр данных:

Year   Category1   Category2   Value
1990   A           X           5
1990   B           X           4
1990   A           Y           3
1990   B           Y           1
1990   A           Z           4
1990   B           Z           2
1991   A           X           3
1991   B           X           2
1991   A           Y           8
...

Я хотел бы объединить наблюдения X и Y в категории 2 путем суммирования столбца «Значение» в новое наблюдение, сохраняя год и группы категории 2:

Year   Category1   Category2   Value
1990   A           X+Y         8
1990   A           Z           4
1990   B           Z           2
1990   B           X+Y         5
1991   A           X+Y         11
...

Ответы [ 4 ]

3 голосов
/ 26 сентября 2019

Предполагая, что это единственные уникальные значения в Category2:

df <-data.frame(
  Year = c(rep(1990, 6), rep(1991,3)),
  Category1 = c("A","B", "A", "B", "A","B","A","B","A"),
  Category2 = c("X","X","Y","Y","Z","Z","X","X","Y"),
  Value = c(5,4,3,1,4,2,3,2,8)
)


df %>% 
  mutate(Category2 = ifelse(Category2 == "Z", "Z", "X+Y")) %>% 
  group_by(Year, Category1, Category2) %>% 
  summarise(Value = sum(Value))

# A tibble: 6 x 4
# Groups:   Year, Category1 [4]
   Year Category1 Category2 Value
  <dbl> <fct>     <chr>     <dbl>
1  1990 A         X+Y           8
2  1990 A         Z             4
3  1990 B         X+Y           5
4  1990 B         Z             2
5  1991 A         X+Y          11
6  1991 B         X+Y           2
1 голос
/ 26 сентября 2019

В качестве альтернативы это также должно работать:

library(dplyr)
df %>%
  spread(Category2,Value, fill = 0) %>%
  mutate("X+Y" = X+Y) %>%
  select(-X,-Y) %>%
  gather(Category2,Value,-Year,-Category1) %>%
  group_by(Year,Category1,Category2) %>%
  summarise(Value = sum(Value, na.rm = TRUE))
1 голос
/ 26 сентября 2019

Я сделаю контрейлер на mfidino.Если есть и другие значения, кроме X, Y и Z, вы можете использовать

Category2 %in% c('X', 'Y')

Это будет выглядеть следующим образом:

df <- tribble(
  ~Year,   ~Category1,   ~Category2,   ~Value,
  1990,   'A',           'X',           5,
  1990,   'B',           'X',           4,
  1990,   'A',           'Y',           3,
  1990,   'B',           'Y',           1,
  1990,   'A',           'Z',           4,
  1990,   'B',           'Z',           2,
  1991,   'A',           'X',           3,
  1991,   'B',           'X',           2,
  1991,   'A',           'Y',           8
)

df %>% 
  mutate(
    Category2 = if_else(Category2 %in% c('X', 'Y'), 'X+Y', Category2)
  ) %>% 
  group_by(Year, Category1, Category2) %>% 
  summarise(
    Value = sum(Value)
  )
# A tibble: 6 x 4
# Groups:   Year, Category1 [4]
   Year Category1 Category2 Value
  <dbl> <chr>     <chr>     <dbl>
1  1990 A         X+Y           8
2  1990 A         Z             4
3  1990 B         X+Y           5
4  1990 B         Z             2
5  1991 A         X+Y          11
6  1991 B         X+Y           2
1 голос
/ 26 сентября 2019

Вы можете суммировать по Year, Category1 и временной логической переменной, если Category2 равно X или Y.После этого требуется небольшая очистка, но получается нужный вам результат.

library(dplyr)

df %>%
  group_by(Year, Category1, temp = Category2 %in% c("X", "Y")) %>%
  summarise(Category2 = paste(Category2, collapse = "+"),
            Value = sum(Value)) %>%
  select(-temp) %>%
  filter(!Category2 %in% c("X", "Y"))

# A tibble: 5 x 4
# Groups:   Year, Category1 [3]
   Year Category1 Category2 Value
  <int> <fct>     <chr>     <int>
1  1990 A         Z             4
2  1990 A         X+Y           8
3  1990 B         Z             2
4  1990 B         X+Y           5
5  1991 A         X+Y          11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...