Объединение нескольких фреймов данных в папке с разными именами столбцов

#r

#r

Вопрос:

У меня есть несколько больших фреймов данных, каждая строка которых имеет уникальный идентификатор, и каждый фрейм данных может иметь разные наборы имен столбцов (некоторые совпадают, а некоторые нет). Я хотел бы, чтобы все фреймы данных были объединены в один фрейм данных. В настоящее время я использую smartbind функцию в gtools для связывания небольших фреймов данных, таких как в примере ниже (и результат — это то, что мне нужно).

 df1 <- data.frame("ID" = c(1,2,3))
df1$A <- c(1, 2, 3)
df1$B <- c("a", "d", "g")
df1


df2 <- data.frame("ID" = c(7,9,10))
df2$A <- c(5, 6, 7)
df2$C <- c("f", "bv", "gn")
df2


df3 <- data.frame("ID" = c(11,12,13))
df3$A <- c("g", "h", 7)
df3$B <- c("f", "bv", "gn")
df3$D <- c(1, 5, 7)
df3

gtools::smartbind(df1,df2,df3)

    ID A    B    C  D
1:1  1 1    a <NA> NA
1:2  2 2    d <NA> NA
1:3  3 3    g <NA> NA
2:1  7 5 <NA>    f NA
2:2  9 6 <NA>   bv NA
2:3 10 7 <NA>   gn NA
3:1 11 g    f <NA>  1
3:2 12 h   bv <NA>  5
3:3 13 7   gn <NA>  7
  

Хотя это хорошее решение, это довольно ручной процесс (и я читал, что smartbind не идеален для больших фреймов данных?). В идеале я хотел бы иметь код, который позволил бы мне связать несколько файлов .csv в папке. В настоящее время у меня есть код, который объединяет несколько файлов .csv в папке (ниже), но это решение для объединения множества фреймов данных, а не решение для привязки нескольких больших фреймов данных, которые имеют разные наборы имен столбцов.

Ниже приведен код, который я использую для объединения нескольких файлов в папке:

 data_all <- list.files(path = "C:/Users/Documents/path/",     
                       pattern = "*.csv", full.names = TRUE) %>% 
            lapply(readr::read_csv) 

merged_files <- data_all %>% purrr::reduce(full_join, by = "ID") 
  

Ответ №1:

Вы можете использовать do.call для объединения списка фреймов данных с помощью smartbind .

 do.call(gtools::smartbind, data_all)
  

smartbind не требует классов столбцов одного и того же типа и изменяет класс неявно.


Если вы преобразуете классы явно, вы также можете сделать это с помощью tidyverse функций.

 library(dplyr)
library(purrr)

map_df(data_all, ~.x %>% mutate(across(-1, as.character)))

#  ID A    B    C    D
#1  1 1    a <NA> <NA>
#2  2 2    d <NA> <NA>
#3  3 3    g <NA> <NA>
#4  7 5 <NA>    f <NA>
#5  9 6 <NA>   bv <NA>
#6 10 7 <NA>   gn <NA>
#7 11 g    f <NA>    1
#8 12 h   bv <NA>    5
#9 13 7   gn <NA>    7