web-dev-qa-db-ja.com

ループで複数のdata.framesを1つのdata.frameにマージします

mergeいくつかのdata.framesを1つのdata.frameにしようとしています。私はファイルの全リストを持っているので、ループ構造でそれをやろうとしています。

これまでのところ、ループアプローチは適切に機能します。しかし、それはかなり非効率的に見え、より速くて簡単なアプローチがあるかどうか疑問に思っています。

シナリオは次のとおりです。いくつかの.csvファイルを含むディレクトリがあります。各ファイルには、マージ変数として使用できる同じ識別子が含まれています。ファイルのサイズがかなり大きいので、すべてのファイルを一度に読み取るのではなく、各ファイルを一度に1つずつRに読み込むことを考えました。したがって、ディレクトリのすべてのファイルをlist.filesで取得し、最初の2つのファイルを読み取ります。その後、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)

次に、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)
}

それはうまく機能しますが、仕事を完了するためのよりエレガントな方法があるかどうか疑問に思っていましたか?

28
mropa

stackoverflowに関連する質問 を詳しく確認することをお勧めします。

私はこれに2つのステップでアプローチします:(plyrを使用して)すべてのデータをインポートしてから、それらを結合します。

filenames <- list.files(path=".../tempDataFolder/", full.names=TRUE)
library(plyr)
import.list <- llply(filenames, read.csv)

これで、マージする必要のあるすべてのファイルのリストが表示されます。これを行うには多くの方法がありますが、ここに1つのアプローチがあります(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)
39
Shane

私が間違っていないのであれば、かなり単純な変更で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
Ken Williams