Использование dplyr expand для получения комбинации переменных, присутствующих в данных?

#r #dplyr

#r #dplyr

Вопрос:

Новичок в R и пытаюсь использовать функции расширения и вложенности dplyr для получения «полного» подмножества моих данных. У меня есть переменная ID и переменная year, и я хотел бы работать только с данными, где для каждого идентификатора в заданном диапазоне есть год. В приведенном ниже примере я бы хотел, чтобы функция возвращала набор данных с A и C, но не B, поскольку для 2020 года отсутствует неявное значение.

Когда я пытаюсь это сделать, я получаю ошибку tibble о том, что столбцы не имеют совместимых размеров. Ниже приведен мой пример и ошибка, которую я получаю. Я уверен, что делаю что-то не так, но я попробовал несколько подходов и не смог решить проблему.

 example <- tibble(
  ID = c('A','A','A','B','B','C','C','C'),
  YEAR = c(2018,2019,2020,2018,2019,2018,2019,2020)
)


full_set <- example %>%
  tidyr::expand(nesting(ID, YEAR = 2018:2020))

Error: Tibble columns must have compatible sizes. * Size 8: Existing data. * Size 3: Column `YEAR`. i Only values of size one are recycled.
  

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

1. full_set <- example %>% filter(YEAR %in% 2018:2020) ?

Ответ №1:

Вы можете использовать complete() from tidyr для генерации всех комбинаций ID и YEAR . flag Является вспомогательным для фильтрации тех, ID которые отсутствуют YEAR .

 library(dplyr)
library(tidyr)

example %>%
  mutate(flag = TRUE) %>%
  complete(ID, YEAR) %>%
  filter(!ID %in% ID[is.na(flag)]) %>%
  select(-flag)

# # A tibble: 6 x 2
#   ID     YEAR
#   <chr> <dbl>
# 1 A      2018
# 2 A      2019
# 3 A      2020
# 4 C      2018
# 5 C      2019
# 6 C      2020
  

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

1. Это более краткая версия того, что я также опубликовал. Спасибо! Будет помечено как правильное.

Ответ №2:

Может быть, это может быть полезно:

 library(tidyverse)
#Code
example %>% mutate(min=min(YEAR),max=max(YEAR)) %>%
  filter(ID!='C') %>%
  rowwise() %>%
  do(data.frame(ID = .$ID, year = seq(.$min, .$max, by = 1)))
  

Вывод:

 # A tibble: 15 x 2
# Rowwise: 
   ID     year
   <fct> <dbl>
 1 A      2018
 2 A      2019
 3 A      2020
 4 A      2018
 5 A      2019
 6 A      2020
 7 A      2018
 8 A      2019
 9 A      2020
10 B      2018
11 B      2019
12 B      2020
13 B      2018
14 B      2019
15 B      2020
  

Дайте мне знать, работает ли это для вас.

Ответ №3:

Спасибо за помощь. Мне удалось найти решение, близкое к тому, что я искал, но не совсем самое краткое. Я решил опубликовать здесь для потомков и всегда открыт для предложений по очистке кода.

 in_data <- example %>%
  tidyr::expand(nesting(ID, YEAR))

all <- example %>%
  tidyr::expand(ID,YEAR)

missing <- all %>%
  anti_join(in_data)

complete <- example %>%
  filter(!ID %in% unique(missing$ID))
  

Вывод:

 # A tibble: 6 x 2
  ID     YEAR
  <chr> <dbl>
1 A      2018
2 A      2019
3 A      2020
4 C      2018
5 C      2019
6 C      2020