Использование R и purrr для объединения нескольких фреймов данных с использованием списка списков с pmap - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь объединить кадры данных, которые встроены в список, с помощью pmap.

library(purrr)
library(plyr)
# Create a list of 5 data frames
create_df <- function(){
      map(1:5, ~ data.frame(country = c("USA", "CHINA", "JAPAN", "FRANCE"),
                                         col = sample.int(100, 4))
      )
    }
# Create a list of lists
list_of_list_of_dataframes <- map(1:3, ~ create_df())
# join the first element of the 3 lists together. 
list_of_dataframes <- pmap(list_of_list_of_dataframes, join_all, by = 'country', type = 'left')

Проблема в том, что эта join_all функция из plyr, похоже, не работает. Я получаю ошибку: Error in .f(.l[[c(1L, i)]], .l[[c(2L, i)]], .l[[c(3L, i)]], ...) : unused argument (.l[[c(3, i)]])

Я могу сделать list_of_dataframes <- pmap(list_of_list_of_dataframes, cbind), чтобы связать кадры данных вместе, но он не удаляет столбцы индекса, которые я тоже сопоставляю, и предполагает, что порядок левых столбцов одинаков.

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Самый простой способ - использовать bind_cols, а затем select только нужные столбцы

library(tidyverse)

set.seed(123456)

# Create a list of 5 data frames
create_df <- function(){
  map(1:5, ~ data.frame(country = c("USA", "CHINA", "JAPAN", "FRANCE"),
                        col = sample.int(100, 4))
  )
}

# Create a list of lists
list_of_list_of_dataframes <- map(1:3, ~ create_df())
str(list_of_list_of_dataframes, max.level = 1)

#> List of 3
#>  $ :List of 5
#>  $ :List of 5
#>  $ :List of 5

pmap(list_of_list_of_dataframes, bind_cols) %>% 
  map(~ select(.x, country, matches("col")))

#> [[1]]
#>   country col col1 col2
#> 1     USA  80   16   23
#> 2   CHINA  75    8   74
#> 3   JAPAN  39   13   88
#> 4  FRANCE  34   17   29
#> 
#> [[2]]
#>   country col col1 col2
#> 1     USA  37   48   52
#> 2   CHINA  20   70   44
#> 3   JAPAN  53   87   57
#> 4  FRANCE  10   86   72
#> 
#> [[3]]
#>   country col col1 col2
#> 1     USA  99   86   68
#> 2   CHINA  17   17   36
#> 3   JAPAN  79   52   33
#> 4  FRANCE  58   85   73
#> 
#> [[4]]
#>   country col col1 col2
#> 1     USA  91   24   51
#> 2   CHINA  88   12   86
#> 3   JAPAN  98   81   75
#> 4  FRANCE  87    8   94
#> 
#> [[5]]
#>   country col col1 col2
#> 1     USA  88   96   84
#> 2   CHINA  20   87   83
#> 3   JAPAN  33   70   27
#> 4  FRANCE  76   59   18

Создано в 2018-07-05 пакетом представ. (v0.2.0.9000).

0 голосов
/ 05 июля 2018

Вы можете использовать dplyr left_join + purrr lower и map2. Но он менее читабелен, чем ответ @ Tung.

reduce(list_of_list_of_dataframes, map2, left_join, by = "country")
[[1]]
  country col.x col.y col
1     USA    82    31  59
2   CHINA     7    65  29
3   JAPAN    62    58  52
4  FRANCE    70    88  35

[[2]]
  country col.x col.y col
1     USA    17    77  23
2   CHINA     5    86  92
3   JAPAN    70    55  73
4  FRANCE    68    42  13

[[3]]
  country col.x col.y col
1     USA    51    10  20
2   CHINA    60    82  65
3   JAPAN    65    90  56
4  FRANCE    64    30  10

[[4]]
  country col.x col.y col
1     USA     9    53  36
2   CHINA    60     5  89
3   JAPAN    51    88  69
4  FRANCE     6    14  11

[[5]]
  country col.x col.y col
1     USA    63    30  94
2   CHINA    92    16  21
3   JAPAN    11    52  27
4  FRANCE    58   100  66
...