R でのデータ フレームのマージ: 完全一致および部分一致

⚡ スマートサマリー

Rにおけるデータフレームのマージは、1つ以上の共通キー列に基づいて2つのテーブルを結合します。merge()関数は、内部結合、左結合、右結合、および完全結合に対応しており、このチュートリアルでは完全一致と部分一致の両方について説明します。

  • 🔑 主要な列: merge() は、by または、各フレームでキーが異なる名前を持つ場合は by.x と by.y で結合します。
  • 🔗 試合全体: デフォルトの内部結合では、キーが両方のデータフレームに存在する行のみが保持されます。
  • 🧩 部分一致: all.x = TRUE に設定すると、最初のフレームのすべての行が保持され、ギャップが NA で埋められます。
  • 📐 寸法チェック: マージの前後で dim() を比較して、結合によって失われたり重複したりした行を検出します。
  • ⚙️ コントロールに参加する: all、all.x、all.yフラグは、内側、左、右、または外側全体の動作を選択します。
  • 🛠️ 現代的な代替案: dplyrは動詞自体に各結合名を記述し、元の行順序を保持します。

R でデータ フレームをマージする

多くの場合、複数のソースからのデータが存在します。 分析を実行するには、次のことを行う必要があります。 マージ XNUMX つのデータフレームと XNUMX つ以上のデータフレーム 共通キー変数.

Rにおけるマージ(結合)の種類

例題に取り組む前に、merge() 関数が SQL ユーザーが期待するすべての結合タイプを実行できることを知っておくと便利です。その動作は、別の関数名ではなく、all、all.x、all.y の引数によって制御されます。

結合タイプ 列は維持された merge() 呼び出し dplyr と同等のもの
内部結合(デフォルト) 両方のフレームに存在するキーのみ merge(x, y, by = “k”) inner_join(x, y, by = “k”)
左外部結合 yに一致する行がないx、NAのすべての行 merge(x, y, by = “k”, all.x = TRUE) left_join(x, y, by = “k”)
右外部結合 y のすべての行は、x に一致する行がないため NA です。 merge(x, y, by = “k”, all.y = TRUE) right_join(x, y, by = “k”)
完全外部結合 両方のフレームのすべての行 merge(x, y, by = “k”, all = TRUE) full_join(x, y, by = “k”)
クロスジョイン 行のすべての組み合わせ merge(x, y, by = NULL) cross_join(x, y)

最初の電話をかける前に、覚えておくべき点が2つあります。

  • by を省略すると、R は 2 つのフレームが共有するすべての列名でマージを実行しますが、これはほとんどの場合望ましくありません。
  • merge() は結果をキー列でソートします。入力された順序を維持するには、sort = FALSE を渡してください。

完全一致

完全一致の場合、宛先テーブルに対応する値のみが返されます。一致しない行は新しいデータフレームから削除されます。一方、部分一致の場合は、該当する行が保持され、欠落している列にはNAが挿入されます。

簡単な例を見てみましょう 内部結合。 内部結合キーワードは、両方のテーブルで一致する値を持つレコードを選択します。 XNUMX つのデータセットを結合するには、merge() 関数を使用できます。 XNUMX つの引数を使用します。

merge(x, y, by.x = x, by.y = y)

Arguments:
-x: The origin data frame
-y: The data frame to merge
-by.x: The column used for merging in x data frame. Column x to merge on
-by.y: The column used for merging in y data frame. Column y to merge on

例:

変数を使用して最初のデータセットを作成する

  • 国籍

変数を使用して XNUMX 番目のデータセットを作成する

  • 映画

共通のキー変数は姓です。両方をマージできます。 データフレーム そして、次元が7×3であることを確認してください。

データフレームにstringsAsFactors=FALSEを追加するのは、 R 文字列を変換して 要因; 変数は文字ベクトルのままにしておく必要があります。R 4.0.0 以降、これは data.frame() のデフォルトになっているため、新しいコードでは引数は省略可能で、古いコードでも問題ありません。

# Create origin dataframe(

producers <- data.frame(   
    surname =  c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"),    
    nationality = c("US","US","UK","US","Poland"),    
    stringsAsFactors=FALSE)

# Create destination dataframe
movies <- data.frame(    
    surname = c("Spielberg",
		"Scorsese",
                "Hitchcock",
              	"Hitchcock",
                "Spielberg",
                "Tarantino",
                "Polanski"),    
    title = c("Super 8",
    		"Taxi Driver",
    		"Psycho",
    		"North by Northwest",
    		"Catch Me If You Can",
    		"Reservoir Dogs","Chinatown"),                
     		stringsAsFactors=FALSE)

# Merge two datasets
m1 <- merge(producers, movies, by.x = "surname")
m1
dim(m1)

出力:

surname		nationality		title
1 Hitchcock		UK		Psycho
2 Hitchcock		UK		North by Northwest
3 Polanski		Poland		Chinatown
4 Scorsese		US		Taxi Driver
5 Spielberg		US		Super 8
6 Spielberg		US		Catch Me If You Can
7 Tarantino		US		Reservoir Dogs

共通キー変数の名前が異なる場合は、データフレームを結合してみましょう。

ムービーデータフレームでは姓を名前に変更します。 関数 Identify(x1, x2) を使用して、両方のデータフレームが同一かどうかを確認します。

# Change name of ` movies ` dataframe
colnames(movies)[colnames(movies) == 'surname'] <- 'name'
# Merge with different key value
m2 <- merge(producers, movies, by.x = "surname", by.y = "name")
# Print head of the data
head(m2)

出力:

##surname     nationality		title
## 1 Hitchcock          UK		Psycho
## 2 Hitchcock          UK		North by Northwest
## 3 Polanski          Poland		Chinatown
## 4 Scorsese           US		Taxi Driver
## 5 Spielberg          US		Super 8
## 6 Spielberg          US		Catch Me If You Can
# Check if data are identical
identical(m1, m2)

出力:

## [1] TRUE

これは、列名が異なっていてもマージ操作が実行されることを示しています。

部分一致

上記の内部結合では、対応するものがないものは静かに削除されます。2 つのデータフレームに同じ共通キー変数がないことは驚くべきことではありません。 完全一致、データフレームが返されます x と y の両方のデータ フレームで見つかった行。 と 部分的なマージ、一致する行がない行を他のデータ フレームに保持することが可能です。 これらの行では、通常 y の値が入力される列に NA が含まれます。 これを行うには、all.x= TRUE を設定します。

例えば、映画データフレームの映画参照情報なしに、プロデューサーデータフレームに新しいプロデューサー「ルーカス」を追加できます。all.x=FALSE を設定すると、R は両方のデータセットで一致する値のみを結合します。この場合、プロデューサー「ルーカス」は一方のデータセットに存在しないため、結果には結合されません。

all.x= TRUE を指定した場合と指定しない場合の各出力の次元を見てみましょう。

# Create a new producer
add_producer <-  c('Lucas', 'US')
#  Append it to the ` producer` dataframe
producers <- rbind(producers, add_producer)
# Use a partial merge 
m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE)
m3

出力:

以下のコンソール出力には、ルーカスに関する追加の行が表示されており、欠落している映画タイトルにはNAが表示されています。

部分マージのコンソール出力で、タイトル列にNAのLucasが表示されています。

# Compare the dimension of each data frame
dim(m1)

出力:

## [1] 7 3
dim(m2)

出力:

## [1] 7 3
dim(m3)

出力:

## [1] 8 3

ご覧のとおり、新しいデータフレームは8×3で、m1とm2の7×3と比較して大きくなっています。Rは、映画データフレームに該当する行がないプロデューサーであるルーカスのタイトル列にNAを入力します。

Rにおけるmerge()とdplyrの結合機能の比較

Base R は、1 つの関数と一連のフラグを使用してすべての結合を解決します。 dplyr パッケージでは、各結合にそれぞれ固有の動詞が割り当てられており、多くのチームにとってパイプライン内で読みやすいものとなっている。

基準 ベースマージ() dplyr が参加します
結合を選択する all.x / all.y / allフラグ 動詞名: left_join()、full_join()
行順 sort = FALSEでない限り、キーでソートされます。 左側のテーブルの順序は保持されます
大型フレームでのスピード もっとゆっくり 一般に速い
キー列が欠落しています 遅延して失敗するか、間違った列でマージされる エラーはすぐに
依存関係 ベースR、インストール不要 dplyrパッケージが必要です

上記に示した2つのマージは、dplyr動詞に直接変換されます。

library(dplyr)
# Same inner join as merge(producers, movies, by.x = "surname", by.y = "name")
m4 <- inner_join(producers, movies, by = c("surname" = "name"))
# Same partial merge as all.x = TRUE
m5 <- left_join(producers, movies, by = c("surname" = "name"))

依存関係を持たないパッケージ内では、基本の merge() 関数の方が安全な選択肢です。一方、可読性と速度がより重要な対話型分析では、dplyr の方が適しています。

Rにおけるよくあるマージエラーとその修正方法

ほとんどのマージ問題は、エラーメッセージではなく、予期しない行数として現れるため、結合のたびにdim()をチェックする習慣を身につける価値があります。

  • 結果の行数は、どちらの入力の行数よりも多い。 両方のフレームで同じキーが繰り返されると、多対多の結合が発生し、R はそのすべての組み合わせを返します。マージする前に、table(duplicated(x$k)) を使用してキーを確認してください。
  • 結果は空です。 キーとなる列は通常、型が異なっていたり、末尾に空白が含まれていたりします。マージする前に、両方のフレームに対してstr()を実行し、trimws()でキーをクリーンアップしてください。
  • 列は title.x と title.y の形式で返されます。 どちらのフレームにも、同じ名前の非キー列が含まれています。出典を明確にするために、suffixes = c(“_producer”, “_film”) を渡してください。
  • 行の並び順が変わってしまいました。 merge() はデフォルトでキーに基づいてソートします。sort = FALSE を追加するか、 明示的な種類 その後。
  • 重要な比較は、いくつかの要因において失敗している。 因子レベルではなく文字を比較します。古いRのデフォルト設定で作成されたフレームをマージする前に、キーをas.character()で囲みます。

同じマージを繰り返し実行する必要がある場合は、 ユーザー定義関数 そのため、引数は実行間でずれることはありません。

よくあるご質問

Rは、2つのフレームが共有するすべての列名に基づいてマージを実行します。共有列が1つだけの場合は便利ですが、複数ある場合は結果を暗黙的に絞り込み、共有列がない場合はクロス結合を返します。キーを明示的に指定することで、これら3つの予期せぬ事態をすべて回避できます。

単一の merge() 呼び出しでは行えません。呼び出しを連結するか、Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3)) を使用してリストを畳み込んでください。重複するキーはすぐに増えてしまうため、各ステップの後に行数を確認してください。

どちらのフレームにも同じ名前の非キー列が含まれているため、R はそれらを区別します。コピーに意味のある名前を付けるには、suffixes = c(“_producer”, “_film”) を渡すか、マージする前に冗長な列を削除してください。

いいえ。merge() はデフォルトでキー列に基づいて結果をソートします。入力された順序を維持するには sort = FALSE を渡すか、 dplyr join は、左側のフレームの順序を保持します。

ベクトルを指定します: merge(x, y, by = c(“surname”, “year”))。名前が異なる場合は、一致するベクトルを by.x と by.y に渡します。両方のベクトルは、列を同じ順序でリストする必要があります。

`by = “row.names”` または省略形の `by = 0` を使用してください。R は行名を `Row.names` という列として追加しますが、通常は分析を続ける前にこの列の名前を変更するか削除する必要があります。

2つのフレームと行数を説明すると、AIアシスタントが重複キーが原因である可能性が高いと指摘し、duplicated() チェックを提案します。結合を変更する前に、ご自身のデータで診断結果を確認してください。

Yes. Rstudio デスクトップ版2023.09.0以降ではオプトイン方式が採用されています。 GitHubコパイロット コメントからマージを作成する統合機能。選択された結合タイプを確認してください。誤ったフラグを設定すると、行数が意図せず変更されてしまう可能性があります。