基于R中的数据帧名称合并存储在不同长度列表中的数据帧

时间:2019-11-11 22:09:26

标签: r

我有以下两个列表:

A_1 <- data.frame(col1 = 1:5, col2 = rnorm(5))
A_2 <- data.frame(col1 = 1:5, col2 = rnorm(5))
B_1 <- data.frame(col1 = 1:5, col2 = rnorm(5))
B_2 <- data.frame(col1 = 1:5, col2 = rnorm(5))
B_3 <- data.frame(col1 = 1:5, col2 = rnorm(5))
C_1 <- data.frame(col1 = 1:5, col2 = rnorm(5))
list1 <- list(A_1 = A_1, A_2 = A_2, B_1 = B_1, B_2 = B_2, B_3 = B_3, C_1 = C_1)
A <- data.frame(col1 = 1:5, col3 = LETTERS[1:5])
B <- data.frame(col1 = 1:5, col3 = LETTERS[6:10])
C <- data.frame(col1 = 1:5, col3 = LETTERS[11:15])
list2 <- list(A = A, B = B, C = C)

我想根据数据帧名称中的字母,将list1的数据帧与list2的数据帧合并到col1列。换句话说,我想将A_1的{​​{1}}与list1的{​​{1}}合并;我想将A的{​​{1}}与list2的{​​{1}}合并;我想将A_2的{​​{1}}与list1的{​​{1}}合并;我想将A的{​​{1}}与list2的{​​{1}}合并;我想将B_1的{​​{1}}与list1的{​​{1}}合并;我想将B的{​​{1}}与list2的{​​{1}}合并。数据框的结果列表应如下所示:

B_2

我该怎么做?谢谢!

2 个答案:

答案 0 :(得分:3)

match列表名称,然后循环使用Mapmerge每个列表中的适当数据集:

m <- match(substr(names(list1),1,1), names(list2))
Map(merge, list1, list2[m], by="col1")

等效的purrr/dplyr/tidyverse为:

map2(list1, list2[m], left_join)

答案 1 :(得分:0)

如何合并两个包含小数据框的大数据框,然后在结果大数据框内合并小数据框? (yo dawg :))当然,@ thelatemail答案更优雅,更有效,但我只是认为这是说明tidyverse功能的好例子。

我们首先定义两个大数据框,其中包含list1list2中的数据框。

library(dplyr)
library(purrr)

bigdf1 <- 
  tibble(
    name1 = names(list1),
    df1   = list1
  ) %>% 
  mutate(name2 = substr(name1, 1, 1))
bigdf1
#> # A tibble: 6 x 3
#>   name1 df1              name2
#>   <chr> <named list>     <chr>
#> 1 A_1   <df[,2] [5 × 2]> A    
#> 2 A_2   <df[,2] [5 × 2]> A    
#> 3 B_1   <df[,2] [5 × 2]> B    
#> 4 B_2   <df[,2] [5 × 2]> B    
#> 5 B_3   <df[,2] [5 × 2]> B    
#> 6 C_1   <df[,2] [5 × 2]> C

bigdf2 <-
  tibble(
    name2 = names(list2),
    df2   = list2
  )
bigdf2
#> # A tibble: 3 x 2
#>   name2 df2             
#>   <chr> <named list>    
#> 1 A     <df[,2] [5 × 2]>
#> 2 B     <df[,2] [5 × 2]>
#> 3 C     <df[,2] [5 × 2]>

然后我们用name2合并它们,然后合并内部的小数据框。

bigdf <-
  left_join(bigdf1, bigdf2, by = "name2") %>% 
  mutate(df_res = map2(df1, df2, left_join, by = "col1")) %>% 
  mutate(df_res = set_names(df_res, name1))
bigdf
#> # A tibble: 6 x 5
#>   name1 df1              name2 df2              df_res          
#>   <chr> <list>           <chr> <list>           <named list>    
#> 1 A_1   <df[,2] [5 × 2]> A     <df[,2] [5 × 2]> <df[,3] [5 × 3]>
#> 2 A_2   <df[,2] [5 × 2]> A     <df[,2] [5 × 2]> <df[,3] [5 × 3]>
#> 3 B_1   <df[,2] [5 × 2]> B     <df[,2] [5 × 2]> <df[,3] [5 × 3]>
#> 4 B_2   <df[,2] [5 × 2]> B     <df[,2] [5 × 2]> <df[,3] [5 × 3]>
#> 5 B_3   <df[,2] [5 × 2]> B     <df[,2] [5 × 2]> <df[,3] [5 × 3]>
#> 6 C_1   <df[,2] [5 × 2]> C     <df[,2] [5 × 2]> <df[,3] [5 × 3]>

然后我们需要bigdf$df_res