Удаление строк с несколькими NA с помощью group_by в dplyr - PullRequest
0 голосов
/ 02 мая 2018

У меня есть этот игрушечный фрейм данных:

df <- data.frame(id=c(1,1,2,3,4,4),p_id=c(1001,1001,1002,1003,1004,1004),x=c(1,NA,1,2,NA,1),y=c(NA,5,4,NA,6,NA),z=c(NA,NA,2,3,NA,4))

id p_id  x  y   z
1  1001  1  NA  NA
1  1001 NA  5   NA
2  1002  1  4    2
3  1003  2  NA   3
4  1004 NA  6   NA
4  1004  1  NA   4

Я бы хотел получить окончательный вывод с удалением уникальных строк 'p_id' и нежелательных значений NA из x, y и z (в идеале, должно работать на любом количестве столбцов). Пример вывода:

p_id    x    y     z
1001    1    5     NaN
1002    1    4     2
1003    2  NaN     3
1004    1    6     4

Я делаю это быстрое решение (не уверен, лучший подход):

df %>% select(-id) %>% group_by(p_id) %>% summarise_all(funs(mean),na.rm=T) %>% ungroup()

Однако этот обходной путь очень медленный при применении к большому кадру данных (2500 x 650), и он создает нежелательные NA для нормальных ячеек. Также для контекста, дублированные строки p_id с NA в этом df происходят из функции расширения.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Вероятно, вы можете сойти с tidyr::fill(), за которым следует summarize

 df %>% 
   group_by(id) %>%  
   fill(x,y,z, .direction = "up") %>% 
   summarise_all(first)
#> # A tibble: 4 x 5
#>      id  p_id     x     y     z
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1  1001     1     5    NA
#> 2     2  1002     1     4     2
#> 3     3  1003     2    NA     3
#> 4     4  1004     1     6     4
0 голосов
/ 02 мая 2018

После группировки по столбцам 'id' выполните summarise_all, создав условие с if/else для возврата NaN, если все элементы в этом столбце для каждой группы равны NA, иначе принимается не-NA element (в этом примере есть только один не-NA элемент, поэтому мы его поднастроим)

df %>%
  group_by(id, p_id) %>%
  summarise_all(funs(if(all(is.na(.))) NaN else .[!is.na(.)]))
# A tibble: 4 x 5
# Groups:   id [?]
#     id  p_id     x     y     z
#  <dbl> <dbl> <dbl> <dbl> <dbl>
#1     1  1001     1     5   NaN
#2     2  1002     1     4     2
#3     3  1003     2   NaN     3
#4     4  1004     1     6     4

Если для каждой комбинации идентификаторов групп больше, чем не-NA значения, то мы можем использовать mean (как показано в посте ОП)

df %>% 
  group_by(id, p_id) %>% 
  summarise_all(funs(if(all(is.na(.))) NaN else mean(., na.rm = TRUE)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...