Scal kilka danych.ramki w jedno dane.ramka z pętelką
Staram się merge
kilka data.frames
w jeden data.frame
. Ponieważ mam całą listę plików, próbuję to zrobić za pomocą struktury pętli.
Do tej pory podejście pętli działa dobrze. Wygląda to jednak dość nieefektywnie i zastanawiam się, czy istnieje szybsze i łatwiejsze podejście.
Oto scenariusz:
Mam katalog z kilkoma plikami .csv
. Każdy plik zawiera ten sam identyfikator, który może być używany jako zmienna fuzji. Ponieważ pliki są dość duże I myślałem, że każdy plik po jednym na raz do R zamiast odczytywać wszystkie pliki na raz.
Pobieram więc wszystkie pliki katalogu z list.files
i czytam w dwóch pierwszych plikach. Następnie używam merge
, aby uzyskać jeden 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)
Teraz używam pętli for
, aby pobrać wszystkie pozostałe pliki .csv
i merge
do już istniejących 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)
}
Mimo, że działa dobrze, zastanawiałem się, czy jest bardziej elegancki sposób, aby wykonać zadanie?
2 answers
Możesz przyjrzeć się bliżej powiązanemu Pytaniu na temat stackoverflow .
Podchodziłbym do tego w dwóch krokach: zaimportuj wszystkie dane( z plyr
), a następnie połącz je ze sobą:
filenames <- list.files(path=".../tempDataFolder/", full.names=TRUE)
library(plyr)
import.list <- llply(filenames, read.csv)
To da ci listę wszystkich plików, które musisz teraz połączyć. Można to zrobić na wiele sposobów, ale oto jedno podejście (z Reduce
):
data <- Reduce(function(x, y) merge(x, y, all=T,
by=c("COUNTRYNAME", "COUNTRYCODE", "Year")), import.list, accumulate=F)
Alternatywnie możesz to zrobić za pomocą pakietu reshape
, jeśli nie czujesz się komfortowo z Reduce
:
library(reshape)
data <- merge_recurse(import.list)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:01:37
Jeśli się nie mylę, dość prosta zmiana może wyeliminować3:length(FileNames)
kludge:
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)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-05 19:06:28