Я пытаюсь merge
несколько data.frames
в одного data.frame
. Так как у меня есть целый список файлов, я пытаюсь сделать это с циклической структурой.
До сих пор подход цикла хорошо работает. Однако это выглядит довольно неэффективным, и я задаюсь вопросом, существует ли более быстрый и более легкий подход.
Вот сценарий: у Меня есть каталог с несколькими .csv
файлы. Каждый файл содержит тот же идентификатор, который может использоваться в качестве переменной слияния. Так как файлы являются довольно большими в размере я думавший считать каждый файл по одному в R вместо того, чтобы читать все файлы сразу. Таким образом, я получаю все файлы каталога с list.files
и читайте в первых двух файлах. Впоследствии я использую merge
получить тот data.frame
.
FileNames <- list.files(path=".../tempDataFolder/")
FirstFile <- read.csv(file=paste(".../tempDataFolder/", FileNames[1], sep=""),
header=T, na.strings="NULL")
SecondFile <- read.csv(file=paste(".../tempDataFolder/", FileNames[2], sep=""),
header=T, na.strings="NULL")
dataMerge <- merge(FirstFile, SecondFile, by=c("COUNTRYNAME", "COUNTRYCODE", "Year"),
all=T)
Теперь я использую a for
цикл для получения всего остающегося .csv
файлы и merge
их в уже существующий data.frame
:
for(i in 3:length(FileNames)){
ReadInMerge <- read.csv(file=paste(".../tempDataFolder/", FileNames[i], sep=""),
header=T, na.strings="NULL")
dataMerge <- merge(dataMerge, ReadInMerge, by=c("COUNTRYNAME", "COUNTRYCODE", "Year"),
all=T)
}
Даже при том, что это работает просто великолепно, я задавался вопросом, существует ли более изящный способ сделать задание?
Возможно, вы захотите внимательно рассмотреть связанный с вопрос о переполнении стека .
Я подойду к этому в два этапа: импортирую все данные (с помощью плиера
), затем объединим их вместе:
filenames <- list.files(path=".../tempDataFolder/", full.names=TRUE)
library(plyr)
import.list <- llply(filenames, read.csv)
Это даст вам список всех файлов, которые теперь необходимо объединить. Есть много способов сделать это, но есть один подход (с помощью Reduce
):
data <- Reduce(function(x, y) merge(x, y, all=T,
by=c("COUNTRYNAME", "COUNTRYCODE", "Year")), import.list, accumulate=F)
Или вы можете сделать это с помощью пакета reshape
, если вам не нравится Reduce
:
library(reshape)
data <- merge_recurse(import.list)
Если я не ошибаюсь, довольно простое изменение могло бы устранить кладж 3: length (FileNames)
:
FileNames <- list.files(path=".../tempDataFolder/", full.names=TRUE)
dataMerge <- data.frame()
for(f in FileNames){
ReadInMerge <- read.csv(file=f, header=T, na.strings="NULL")
dataMerge <- merge(dataMerge, ReadInMerge,
by=c("COUNTRYNAME", "COUNTRYCODE", "Year"), all=T)
}