在 R 中合并列表中的常见列

combining common columns in a list in R

提问人:Seyma Kalay 提问时间:5/5/2023 更新时间:5/5/2023 访问量:31

问:

我有一个如下所示的列表对象。

df1 <- data_frame(ID = paste0(LETTERS[1],1:4), valueA = seq(0.1,0.4,0.1), Category= "Apples", valueDEF = seq(0.1,0.4,0.1), valueDEF2 = seq(0.1,0.4,0.1) )
df2 <- data_frame(ID = paste0(LETTERS[1],5:8), valueB = seq(0.1,0.4,0.1),  Category= "Apples2")
df3 <- data_frame(ID = paste0(LETTERS[1],9:12), valueC = seq(0.1,0.4,0.1),  Category= "Apples3")

list1 <- list(df1, df2, df3);list1



  [[1]]
# A tibble: 4 × 5
  ID    valueA Category valueDEF valueDEF2
  <chr>  <dbl> <chr>       <dbl>     <dbl>
1 A1       0.1 Apples        0.1       0.1
2 A2       0.2 Apples        0.2       0.2
3 A3       0.3 Apples        0.3       0.3
4 A4       0.4 Apples        0.4       0.4

[[2]]
# A tibble: 4 × 3
  ID    valueB Category
  <chr>  <dbl> <chr>   
1 A5       0.1 Apples2 
2 A6       0.2 Apples2 
3 A7       0.3 Apples2 
4 A8       0.4 Apples2 

[[3]]
# A tibble: 4 × 3
  ID    valueC Category
  <chr>  <dbl> <chr>   
1 A9       0.1 Apples3 
2 A10      0.2 Apples3 
3 A11      0.3 Apples3 
4 A12      0.4 Apples3 

我想根据常见的列名将它们合并到 1 个数据框中。

预期答案

ID Category
A1  Apples 
A2  Apples 
A3  Apples 
A4  Apples 
A5  Apples2 
A6  Apples2
A7  Apples2
A8  Apples2 
A9  Apples3 
A10 Apples3 
A11 Apples3 
A12 Apples3 

如何解决这个问题?提前非常感谢。

r dplyr tidyr 数据操作 整洁

评论


答:

2赞 TarJae 5/5/2023 #1

我们可以使用 .intersect()

  • 为此,我们使用 将 colnames 应用于列表中的每个数据框。lapply()
  • 然后,将生成的列表与函数一起传递给该函数。Reduce()intersect()
  • 最后,我们用来获取单个数据帧:bind_rows()
library(dplyr) #bind_rows()

common_cols <- Reduce(intersect, lapply(list1, colnames))
df_all <- bind_rows(list1)[common_cols]
 ID    Category
   <chr> <chr>   
 1 A1    Apples  
 2 A2    Apples  
 3 A3    Apples  
 4 A4    Apples  
 5 A5    Apples2 
 6 A6    Apples2 
 7 A7    Apples2 
 8 A8    Apples2 
 9 A9    Apples3 
10 A10   Apples3 
11 A11   Apples3 
12 A12   Apples3 
1赞 Joe Robert 5/5/2023 #2

作为对 TarJae 答案的补充,这里有一个单行代码,在函数中使用函数 from:wheretidyselectselectdplyr

library(dplyr)
select(bind_rows(list1) ,
       where(~!any(is.na(.))))