#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