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?

Author: mropa, 2010-02-05

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)
 37
Author: Shane,
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)
}
 1
Author: Ken Williams,
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