リスト内の複数のデータフレームを同時にマージする 質問する

リスト内の複数のデータフレームを同時にマージする 質問する

マージしたいデータフレームのリストが多数あります。ここでの問題は、各データフレームの行数と列数が異なりますが、すべてのデータフレームがキー変数(以下のコードでは"var1"と と呼んでいます)を共有していることです。データフレームの列数が同一であれば、 plyr の と入力するだけ"var2"で済みます。rbindrbind.fillこれで問題は解決するはずですが、今回のデータではそうではありません。

このコマンドは2つのデータフレームでしか機能しないのでmerge、インターネットでアイデアを探しました。こここれは、当時私が使用していた R 2.7.2 では完璧に動作しました。

merge.rec <- function(.list, ...){
    if(length(.list)==1) return(.list[[1]])
    Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}

そして、私は次のように関数を呼び出します:

df <- merge.rec(my.list, by.x = c("var1", "var2"), 
                by.y = c("var1", "var2"), all = T, suffixes=c("", ""))

しかし、2.7.2 以降の R バージョン (2.11 および 2.12 を含む) では、このコードは次のエラーで失敗します。

Error in match.names(clabs, names(xi)) : 
  names do not match previous names

(ちなみに、このエラーに関する他の言及も見受けられます他の場所解決なし)。

これを解決する方法はありますか?

ベストアンサー1

もう一つの具体的な質問はR で dplyr を使用して複数の左結合を実行する方法この質問は重複としてマークされていたので、以下の 3 つのサンプル データ フレームを使用してここで回答します。

x <- data.frame(i = c("a","b","c"), j = 1:3, stringsAsFactors=FALSE)
y <- data.frame(i = c("b","c","d"), k = 4:6, stringsAsFactors=FALSE)
z <- data.frame(i = c("c","d","a"), l = 7:9, stringsAsFactors=FALSE)

答えは、マージを実行する 3 つの異なる方法を表す 3 つのセクションに分かれています。すでにtidyversepurrrパッケージを使用している場合は、おそらくその方法を使用することをお勧めします。比較のために、以下に同じサンプル データセットを使用する基本 R バージョンを示します。


1)パッケージreduceから次のものを結合しますpurrr:

このpurrrパッケージはreduce簡潔な構文を持つ関数を提供します。

library(tidyverse)
list(x, y, z) %>% reduce(left_join, by = "i")
#  A tibble: 3 x 4
#  i       j     k     l
#  <chr> <int> <int> <int>
# 1 a      1    NA     9
# 2 b      2     4    NA
# 3 c      3     5     7

full_joinまたはなどの他の結合も実行できますinner_join

list(x, y, z) %>% reduce(full_join, by = "i")
# A tibble: 4 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 a     1     NA     9
# 2 b     2     4      NA
# 3 c     3     5      7
# 4 d     NA    6      8

list(x, y, z) %>% reduce(inner_join, by = "i")
# A tibble: 1 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 c     3     5     7

2)dplyr::left_join()基数Rの場合Reduce():

list(x,y,z) %>%
    Reduce(function(dtf1,dtf2) left_join(dtf1,dtf2,by="i"), .)

#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7

3) ベース Rmerge()とベース R Reduce():

比較のために、Charles の回答に基づいた左結合の基本 R バージョンを次に示します。

 Reduce(function(dtf1, dtf2) merge(dtf1, dtf2, by = "i", all.x = TRUE),
        list(x,y,z))
#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7

おすすめ記事