Объединение дублированных строк в соответствии с NA в R

#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))
  

на случай, если вам нужна самая ранняя запись для каждого пользователя.