Суммируйте данные с наблюдениями для всех комбинаций факторов - PullRequest
1 голос
/ 21 марта 2020

Иногда желательно иметь полный кадр данных с наблюдениями для всех комбинаций группирующих факторов, даже если они отсутствуют в исходных данных (т. Е. Путем заполнения этих пробелов данными NA).

Рассмотрим следующее пример с mtcars:

mtcars %>% group_by(cyl, gear) %>% dplyr::summarise(N = n())
# A tibble: 8 x 3
# Groups:   cyl [3]
    cyl  gear     N
  <dbl> <dbl> <int>
1     4     3     1
2     4     4     8
3     4     5     2
4     6     3     2
5     6     4     4
6     6     5     1
7     8     3    12
8     8     5     2

При группировании по cyl и gear наблюдения отсутствуют для cyl=8 и gear=4. Можно ли получить эту сводную таблицу простым, надеемся, на основе тидиверса, способом, который включает строку с наблюдениями NA для комбинаций факторов, которые отсутствуют? Например, желаемый результат будет:

# A tibble: 9 x 3
# Groups:   cyl [3]
    cyl  gear     N
  <dbl> <dbl> <int>
1     4     3     1
2     4     4     8
3     4     5     2
4     6     3     2
5     6     4     4
6     6     5     1
7     8     3    12
8     8     4    NA
9     8     5     2

Ответы [ 2 ]

1 голос
/ 21 марта 2020

Если вы преобразуете группы в множители и используете count (альтернатива для group_by с summarise n()) с .drop = FALSE, это завершит пропущенные наблюдения.

library(dplyr)

mtcars %>% mutate_at(vars(cyl, gear), factor) %>% count(cyl, gear, .drop = FALSE)

#  cyl   gear      N
#  <fct> <fct> <int>
#1 4     3         1
#2 4     4         8
#3 4     5         2
#4 6     3         2
#5 6     4         4
#6 6     5         1
#7 8     3        12
#8 8     4         0
#9 8     5         2
1 голос
/ 21 марта 2020

Мы можем использовать complete после удаления атрибутов группы с помощью ungroup

library(dplyr)
library(tidyr)
mtcars %>% 
    group_by(cyl, gear) %>%
    dplyr::summarise(N = n()) %>%
    ungroup %>%
    complete(cyl, gear)
# A tibble: 9 x 3
#    cyl  gear     N
#  <dbl> <dbl> <int>
#1     4     3     1
#2     4     4     8
#3     4     5     2
#4     6     3     2
#5     6     4     4
#6     6     5     1
#7     8     3    12
#8     8     4    NA
#9     8     5     2

Или другой вариант - создать набор комбинированных данных с уникальными элементами столбцов, а затем выполнить left_join (не так просто, как предыдущий)

crossing(cyl = unique(mtcars$cyl), gear = unique(mtcars$gear)) %>% 
    left_join(mtcars %>% 
                  group_by(cyl, gear) %>%
                  dplyr::summarise(N = n()))
...