Объединение фреймов данных, хранящихся в списках разной длины, на основе имен фреймов данных в R - PullRequest
2 голосов
/ 12 ноября 2019

У меня есть два следующих списка:

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 из list1 с A из list2;Я хочу объединить A_2 из list1 с A из list2;Я хочу объединить B_1 с list1 с B с list2;Я хочу объединить B_2 с list1 с B с list2;Я хочу объединить B_3 с list1 с B с list2;Я хочу объединить C_1 с list1 с C с list2. Полученный список фреймов данных должен выглядеть следующим образом:

$A_1
  col1        col2 col3
1    1  0.06356074    A
2    2 -0.08646429    B
3    3  0.65156169    C
4    4  0.83935642    D
5    5 -0.76709566    E

$A_2
  col1       col2 col3
1    1  0.3347519    A
2    2 -1.5905887    B
3    3 -0.6629217    C
4    4 -1.0208914    D
5    5 -0.3978965    E

$B_1
  col1       col2 col3
1    1  0.5910048    F
2    2 -0.7017961    G
3    3  0.4436402    H
4    4  0.5051056    I
5    5  1.9631446    J

$B_2
  col1        col2 col3
1    1  1.59825082    F
2    2  1.12307589    G
3    3  0.55073043    H
4    4  0.06900526    I
5    5 -1.74212727    J

$B_3
  col1         col2 col3
1    1 -3.408669559    F
2    2  0.871771331    G
3    3 -1.811021818    H
4    4  1.735995986    I
5    5 -0.007419926    J

$C_1
  col1       col2 col3
1    1 -0.6678336    K
2    2  1.5844579    L
3    3 -1.4021920    M
4    4 -1.1643714    N
5    5 -0.3893558    O

Как мне это сделать? Спасибо!

Ответы [ 2 ]

3 голосов
/ 12 ноября 2019

match имена списков, затем выполните цикл, используя Map - merge соответствующий набор данных в каждом списке вместе:

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)
0 голосов
/ 12 ноября 2019

Как насчет слияния двух больших фреймов данных, содержащих небольшие фреймы данных, а затем слияния небольших фреймов данных в результирующий большой фрейм данных? ( yo dawg:) ) Конечно, ответ @thelatemail более элегантный и эффективный, но я просто подумал, что это будет классный пример, иллюстрирующий возможности Tidyverse.

Мы начнем с определениядва больших блока данных, содержащих кадры данных из list1 и list2.

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 это то, что нам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...