как объединить данные между строками data.frame на основе одинаковых значений столбцов - PullRequest
1 голос
/ 29 мая 2019

Как бы вы объединили значения между строками, которые имеют одинаковые значения в id_3? Я уверен, что есть более подходящее название для заголовка вопроса, но я изо всех сил пытаюсь найти подходящее название операции / функции для этой процедуры.

library(tidyverse)
id_1 <- c("x12", NA, "a_bc", NA)
id_2 <- c(NA, "gye", NA, "ab_c")
id_3 <- c("qwe", "ert", "abc", "abc")
param_1 <- c(0.21, 1.5, 0.23, NA)
param_12 <- c(0.05, 4.4, NA, 6.3)

df <- data.frame(id_1, id_2, id_3, param_1, param_12)
as_tibble(df)

#    id_1  id_2  id_3  param_1 param_12
#   <fct> <fct> <fct>   <dbl>    <dbl>
#  1 x12   NA    qwe      0.21     0.05
#  2 NA    gye   ert      1.5      4.4 
#  3 a_bc  NA    abc      0.23     NA   
#  4 NA    ab_c  abc      NA       6.3 

желаемый df:

#    id_1  id_2  id_3  param_1 param_12
#   <fct> <fct> <fct>   <dbl>    <dbl>
#  1 x12   NA    qwe     0.21     0.05
#  2 NA    gye   ert     1.5      4.4 
#  3 a_bc  ab_c  abc     0.23     6.3 

обновление - с дополнительными форматами столбцов, такими как символ:

id_1 <- c("x12", NA, "a_bc", NA)
id_2 <- c(NA, "gye", NA, "ab_c")
id_3 <- c("qwe", "ert", "abc", "abc")
param_1 <- c(0.21, 1.5, 0.23, NA)
param_12 <- c(0.05, 4.4, NA, 6.3)
desc_1 <- c("st", NA, "ko", NA)
desc_2 <- c(NA, "lo", NA, "vf")

df <- data.frame(id_1, id_2, id_3, param_1, param_12, desc_1, desc_2)
df <- df %>% mutate(desc_1 = as.character(desc_1), 
                    desc_2 = as.character(desc_2))

 # A tibble: 4 x 7
 #  id_1  id_2  id_3  param_1 param_12 desc_1 desc_2
 #  <fct> <fct> <fct>   <dbl>    <dbl> <chr>  <chr> 
 #1 x12   NA    qwe      0.21     0.05 st     NA    
 #2 NA    gye   ert      1.5      4.4  NA     lo    
 #3 a_bc  NA    abc      0.23    NA    ko     NA    
 #4 NA    ab_c  abc     NA        6.3  NA     vf 

df <- df %>% group_by(id_3) %>% 
      summarise_all(list(~ if(all(is.na(.))) NA else .[!is.na(.)]

`Error: Column `desc_1` can't promote group 1 to character`

1 Ответ

3 голосов
/ 29 мая 2019

Мы можем сгруппировать по 'id_3' и summarise всем столбцам, чтобы получить NA, если все значения в этом конкретном столбце NA для группы или else, удалить NA и вернуть первый не-элемент NA

library(tidyverse)
df %>% 
   group_by(id_3) %>% 
   summarise_all(list(~ if(all(is.na(.))) NA else .[!is.na(.)][1]))
# A tibble: 3 x 5
#  id_3  id_1  id_2  param_1 param_12
#  <fct> <fct> <fct>   <dbl>    <dbl>
#1 abc   a_bc  ab_c     0.23     6.3 
#2 ert   <NA>  gye      1.5      4.4 
#3 qwe   x12   <NA>     0.21     0.05

-Rstudio

enter image description here

Обновление

Во втором наборе данных после преобразования столбцов в класс character OP обнаружил ошибку с if(all(is.na(.))) NA l. Если столбцы имеют одинаковый тип, мы можем указать NA_character, NA_real_, NA_integer_ для отправки правильного NA для каждого типа. Здесь мы не можем этого сделать, но есть одна хакерская опция для возврата 1-го элемента NA в этом столбце, который также будет иметь правильный тип

df %>% 
   group_by(id_3) %>% 
   summarise_all(list(~ if(all(is.na(.))) .[!is.na(.)][1] 
           else .[!is.na(.)]))
# A tibble: 3 x 7
#  id_3  id_1  id_2  param_1 param_12 desc_1 desc_2
#  <fct> <fct> <fct>   <dbl>    <dbl> <chr>  <chr> 
#1 abc   a_bc  ab_c     0.23     6.3  ko     vf    
#2 ert   <NA>  gye      1.5      4.4  <NA>   lo    
#3 qwe   x12   <NA>     0.21     0.05 st     <NA>  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...