Добавьте все отсутствующие строки и столбцы, сопоставив ключ со всеми возможными строками и столбцами

#r #dplyr

#r #dplyr

Вопрос:

Я составляю таблицы количества случаев по годам и возрастной группе для каждого округа. Пример df и векторы всех возможных возрастных групп, лет и округов:

     library(tidyverse)

    df <- data.frame(
      "year" = c(2010, 2010, 2011, 2013, 2014, 2014, 
                 2015, 2015, 2015, 2016),
      "age_group" = c("20-39", "0-19", "0-19", "60-79", 
                      "80-99", "20-39","20-39", "60-79", 
                      "20-39", "80-99"),
      "county" = c("a", "b", "b", "a", "c", "b", "b", 
                   "a", "a", "a")) 

    all_age_groups <- c("0-19", "20-39", "40-59", "60-79", "80-99")

    all_years <- c(2010:2017)

    all_counties <- c("a", "b", "c", "d")
  

В округах «a», «b» и «c» отсутствуют НЕКОТОРЫЕ возрастные группы или годы. В округе «d» отсутствуют ВСЕ возрастные группы и годы (без обращений).

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

     ex_func <- function(df_orig, selectcounty) {
      df_age_group <- data.frame("age_group" = all_age_groups)
      df2 <- df_orig %>%
        filter(county == selectcounty) %>%
        group_by(age_group, year) %>%
        summarise(cases = n()) %>%
        spread(year, cases) %>%
        full_join(., df_age_group, by = "age_group") %>%
        replace(is.na(.), 0) %>%
        ungroup() %>%
        mutate(age_group = factor(age_group, levels = all_age_groups)) %>%
        arrange(age_group)
     df2
    }
  

Но я не смог успешно справиться с отсутствующими столбцами года без ручного создания нового для каждого отсутствующего года с помощью mutate .

Я ищу способ, предпочтительно в dplyr , для:

1) найдите, какие годы из all_years не существуют в виде столбцов в df

2) добавьте столбцы для каждого отсутствующего года

3) сделайте все строки для каждого нового столбца равными 0

4) сохраняйте порядок лет (2010-2017) в столбцах и возрастных группах в df$age_group

более короткая версия желаемого результата для округа «b»:

     df2 <- ex_func(df, "b")

    age_group `2010` `2011 `2012` `2013` `2014 `2015`   
    0-19         1     1     0      0      0     0
    20-39        0     0     0      0      1     1
    40-59        0     0     0      0      0     0
    60-79        0     0     0      0      0     0
    80-99        0     0     0      0      0     0
  

Комментарии:

1. ?tidyr::complete ?

2. library(tidyverse); df %>% mutate(year=factor(year)) %>% group_by(year, age_group, county, .drop=FALSE) %>% tally . .drop=FALSE сохраняет все комбинации. Это работает, только если все группирующие переменные являются классом factor, поэтому я включил код для преобразования year в factor. Остальные столбцы в вашем примере учитываются по умолчанию. Вам понадобится dplyr версия 0.8 или выше.

3. Разве не здорово, что eipi только что помог e (i) pi_n00b?