#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