#r #dplyr #duplicates #na
#r #dplyr #дубликаты #na
Вопрос:
У меня есть набор данных, содержащий дублированные строки по идентификатору, с некоторыми NAS для каждой. Меня интересуют последние наблюдения для каждого идентификатора. Как я могу объединить их, чтобы получить максимальную отдачу от обеих строк (самых ранних и последних)?
df_in <-
data.frame(A = c(as.Date("2020-01-01"), as.Date("2020-01-02"), as.Date("2020-01-02")),
Name = c("Adam","Adam","Rob"),
B = c(1,2,3),
C = c(1,2,3),
D = c(NA,2,3))
df_out <-
data.frame(A = c(as.Date("2020-01-01"), as.Date("2020-01-03")),
Name = c("Adam","Rob"),
B = c(1,3),
C = c(1,3),
D = c(2,3))
Как я могу попросить R извлечь ближайшее значение в соответствии со столбцом времени (объединить дублированные строки в соответствии с именем переменной) и удалить последнюю??
Комментарии:
1. Вы выполняете прямое заполнение или просто удаляете
NA
s?2. Ссылается ли столбец Name на ID в ваших данных? Почему дата Роба (столбец) меняется на 03?
3. @NelsonGon перенаправляет заполнение, потому что в обоих столбцах чаще всего будут NAS, и это заставит меня потерять обе строки. @ KarthikS Да, извините, это не должно иметь отношения к ситуации Роба. Я просто хочу пояснить, что я хочу объединить разные даты (как можно ближе), заполняя NAS друг друга, группируя по идентификатору (имени)
Ответ №1:
Использование dplyr,
df_in %>% arrange(-A) %>%
filter(!duplicated(Name))
Ответ №2:
Используя dplyr
, вы можете сделать это с помощью нескольких ifelse
команд.
library(dplyr)
df_solution = df_in %>%
group_by(Name) %>%
arrange(A) %>%
mutate(B = ifelse(is.na(B),
ifelse(!is.na(lag(B)), lag(B), lead(B)),
B
),
C = ifelse(is.na(C),
ifelse(!is.na(lag(C)), lag(C), lead(C)),
C
),
D = ifelse(is.na(D),
ifelse(!is.na(lag(D)), lag(D), lead(D)),
D
)
)
Если некоторые записи с одинаковыми Name
NAS находятся до середины таблицы, используйте arrange(-A)
вместо arrange(A)
или оба.
Однако, если у вас большие «дыры» в ваших данных с длинным рядом NA, для удаления всех NA потребуется переход назад и вперед в течение цикла. При таком подходе не будет согласованности в заполнении последних NAS, потому что некоторые будут заполнены предыдущим значением, а некоторые — следующим. Если это так и имеет значение согласованность, это решение не так уж и хорошо.
Я также не уверен, нужна ли вам уникальная запись для каждого имени, но если да, вы также можете сделать
df_filtered = df_solution %>%
group_by(Name) %>%
arrange(A) %>%
filter(A == min(A))
на случай, если вам нужна самая ранняя запись для каждого пользователя.