如何基于相同的列值跨data.frame行合并数据

时间:2019-05-29 18:42:59

标签: r tidyverse

如何在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 个答案:

答案 0 :(得分:3)

如果特定列中的所有值都是summariseNA删除,我们可以对所有列进行'id_3'和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_characterNA_real_NA_integer_为每种类型分配正确的NA。在这里,我们不能这样做,但是有一个hacky选项可以返回该列中的第一个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>