Rでデータフレームを結合する

R
Published

November 28, 2024

データフレームが複数あるとき、扱いやすさのために結合したいときがあります。 また、共通する部分をまとめたいときもあります。 そのようなときに役立つ関数がmerge関数です。

基本的な使い方

id列を共通に持ち、2つのデータフレームd1d2を作成します。 共通のid列以外には、d1rank、とd2scoreという列を持っています。

d1 <- data.frame(id = 1:5, rank = c("A", "A", "B", "C", "A"))
d2 <- data.frame(id = 3:7, score = c(60, 20, 80, 30, 10))
d1
  id rank
1  1    A
2  2    A
3  3    B
4  4    C
5  5    A
d2
  id score
1  3    60
2  4    20
3  5    80
4  6    30
5  7    10

この2つのデータフレームに関して、idを残してrankscoreをくっつけたデータフレームをmerge関数で作成します。 このとき、共通部分とするidキー keyといいます。

基本的な使い方は、merge(データフレーム1, データフレーム2, by = キー)と書きます。

merge(d1, d2, by = "id")
  id rank score
1  3    B    60
2  4    C    20
3  5    A    80

ちなみに、byを除いた場合でも、デフォルトで共通する列名がキーとなる仕様のため、同じ挙動となります。

merge(d1, d2)
  id rank score
1  3    B    60
2  4    C    20
3  5    A    80

全部のデータを残す場合

キーとなるidを全部残したい場合は、all = TRUEを入れます。

merge(d1, d2, all = TRUE)
  id rank score
1  1    A    NA
2  2    A    NA
3  3    B    60
4  4    C    20
5  5    A    80
6  6 <NA>    30
7  7 <NA>    10

足りない要素は欠損値を示すNAで埋められます。 NAはNot Available (利用不可)の意味です。

片方のデータは全部残す場合

d1もしくはd2だけ全部残して結合したいという場合は、all.x = TRUEもしくはall.y = TRUEを入れます。

all.x = TRUEを指定した場合は、最初に指定したデータフレームはすべて残ります。 今回の場合は、d1にあるidrankはすべて残り、d2からscoreをくっつけます。

merge(d1, d2, all.x = TRUE)
  id rank score
1  1    A    NA
2  2    A    NA
3  3    B    60
4  4    C    20
5  5    A    80

all.y = TRUEを指定した場合は、後に指定したデータフレームはすべて残ります。 今回の場合は、d2にあるidscoreはすべて残り、d1からrankをくっつけます。

merge(d1, d2, all.y = TRUE)
  id rank score
1  3    B    60
2  4    C    20
3  5    A    80
4  6 <NA>    30
5  7 <NA>    10

列名が異なる場合

データフレーム同士の列名が異なる場合もあります。 この場合、片方の列名をnames関数などで変更して片方に統一してもよいですが、そのようにしなくとも結合することができます。 例として、d1idd2identifierという異なる列名となっている場合を考えます。 id = identifierだけど、異なる名前でデータフレームが作られているということになります。

d1 <- data.frame(id = 1:5, rank = c("A", "A", "B", "C", "A"))
d2 <- data.frame(identifier = 3:7, score = c(60, 20, 80, 30, 10))
d1
  id rank
1  1    A
2  2    A
3  3    B
4  4    C
5  5    A
d2
  identifier score
1          3    60
2          4    20
3          5    80
4          6    30
5          7    10

by.x = "id"by.y = "identifierと指定すると、1つ目と2つ目のデータフレームの異なる列名を同じキーとして結合できます。

merge(d1, d2, by.x = "id", by.y = "identifier")
  id rank score
1  3    B    60
2  4    C    20
3  5    A    80
merge(d1, d2, by.x = "id", by.y = "identifier", incomparables = NA)
  id rank score
1  3    B    60
2  4    C    20
3  5    A    80

特定の値は結合から省く場合

あまり使うことはないかもしれませんが、キーの特定の値は結合せず結果から省くことができます。 例えば、キーにNAが含まれている場合を考えます。

d1 <- data.frame(id = c(1, 2, NA, 4, 5), rank = c("A", "A", "B", "C", "A"))
d2 <- data.frame(id = c(NA, 4:7), score = c(60, 20, 80, 30, 10))
d1
  id rank
1  1    A
2  2    A
3 NA    B
4  4    C
5  5    A
d2
  id score
1 NA    60
2  4    20
3  5    80
4  6    30
5  7    10

idが3だった部分がNAになっています。 idをキーとしてmerge関数を使用すると、NAという部分で共通しているためそのまま結合されます。

merge(d1, d2, by = "id")
  id rank score
1  4    C    20
2  5    A    80
3 NA    B    60

このようなとき、NAは除いて結合するには、incomparables = NAと指定します。 incomparableは「比較に適さない」という意味になり、比較したくない値を省くことができます。

merge(d1, d2, by = "id", incomparables = NA)
  id rank score
1  4    C    20
2  5    A    80

もちろん、NA以外でも、特定の値は除きたいという場合も有効です。 もう一度、最初のデータフレームを作成します。

d1 <- data.frame(id = 1:5, rank = c("A", "A", "B", "C", "A"))
d2 <- data.frame(id = 3:7, score = c(60, 20, 80, 30, 10))
d1
  id rank
1  1    A
2  2    A
3  3    B
4  4    C
5  5    A
d2
  id score
1  3    60
2  4    20
3  5    80
4  6    30
5  7    10

例えば、idが4のものは除きたいときは、incomparables = 4とします。

merge(d1, d2, by = "id", incomparables = 4)
  id rank score
1  3    B    60
2  5    A    80

idが4の行が存在しないことがわかります。

まとめ

データフレームを結合したいときはmerge関数が有効です。 キーをbyで指定します。 列名が異なる場合は1つ目をby.x、2つ目をby.yで指定します。

キーの値が重複しなくても全部残したい場合はall = TRUEを指定します。 1つ目のデータフレームのキーは全部残したい場合はall.x = TRUE、2つ目はall.y = TRUEを指定します。

特定の値を結合から除きたい場合は、incomparablesで指定します。

生データのCSVやExcelファイルで手動でデータフレームをくっつけるのもよいですが、ミスが生じたり、生データを消去してしまったりする可能性があります。 何より、データが多いと面倒なので、R上でサクッとできると楽ですね。

Back to top