データ分析において、複数のテーブルを結合する操作は非常に重要です。SQLのJOIN操作と同様の処理を、Rのtidyverseパッケージでどのように実現できるかを、患者データと体重データを例にして解説します。 ## 完全なコード ```r # 必要なライブラリの読み込み library(tidyr) library(dplyr) # サンプルデータ1: 患者の基本情報 patients <- data.frame( id = c(1001, 1002, 1003, 1004, 1005), name = c("山田太郎", "田中花子", "佐藤次郎", "鈴木美咲", "高橋健太"), age = c(45, 32, 67, 28, 51) ) # サンプルデータ2: 体重データ weights <- data.frame( id = c(1001, 1002, 1003, 1005, 1006), weight_kg = c(70, 52, 82, 55, 75) ) # INNER JOIN - 両方のデータが存在する患者のみ inner_result <- patients %>% inner_join(weights, by = "id") print("INNER JOIN結果:") print(inner_result) # LEFT JOIN - 全ての患者情報を保持(体重データがない場合はNA) left_result <- patients %>% left_join(weights, by = "id") print("LEFT JOIN結果:") print(left_result) # RIGHT JOIN - 全ての体重データを保持(患者情報がない場合はNA) right_result <- patients %>% right_join(weights, by = "id") print("RIGHT JOIN結果:") print(right_result) # FULL JOIN - 両方のデータを全て保持 full_result <- patients %>% full_join(weights, by = "id") print("FULL JOIN結果:") print(full_result) ``` ## ステップバイステップ解説 ### 1. ライブラリの読み込み ```r library(tidyr) library(dplyr) ``` tidyrとdplyrパッケージを読み込みます。JOIN操作はdplyrの機能ですが、データ処理全般でtidyrも使用することが多いため、両方を読み込んでいます。 ### 2. サンプルデータの作成 まず患者の基本情報を作成します: ```r patients <- data.frame( id = c(1001, 1002, 1003, 1004, 1005), name = c("山田太郎", "田中花子", "佐藤次郎", "鈴木美咲", "高橋健太"), age = c(45, 32, 67, 28, 51) ) ``` ``` > print(patients) id name age 1 1001 山田太郎 45 2 1002 田中花子 32 3 1003 佐藤次郎 67 4 1004 鈴木美咲 28 5 1005 高橋健太 51 ``` 次に体重データを作成します: ```r weights <- data.frame( id = c(1001, 1002, 1003, 1005, 1006), weight_kg = c(70, 52, 82, 55, 75) ) ``` ``` > print(weights) id weight_kg 1 1001 70 2 1002 52 3 1003 82 4 1005 55 5 1006 75 ``` 注目すべき点は、患者データにはid 1004が含まれていますが体重データにはなく、逆に体重データにはid 1006が含まれていますが患者データにはないということです。この違いによって、各JOIN操作の結果がどのように変わるかを確認できます。 ### 3. INNER JOIN(内部結合) ```r inner_result <- patients %>% inner_join(weights, by = "id") ``` ``` > print(inner_result) id name age weight_kg 1 1001 山田太郎 45 70 2 1002 田中花子 32 52 3 1003 佐藤次郎 67 82 4 1005 高橋健太 51 55 ``` INNER JOINは両方のテーブルに存在するレコードのみを返します。id 1004(鈴木美咲)は体重データがないため除外され、id 1006は患者データがないため除外されています。 ### 4. LEFT JOIN(左外部結合) ```r left_result <- patients %>% left_join(weights, by = "id") ``` ``` > print(left_result) id name age weight_kg 1 1001 山田太郎 45 70 2 1002 田中花子 32 52 3 1003 佐藤次郎 67 82 4 1004 鈴木美咲 28 NA 5 1005 高橋健太 51 55 ``` LEFT JOINは左のテーブル(patients)のすべてのレコードを保持します。id 1004(鈴木美咲)の体重データがないため、weight_kgにはNAが入ります。 ### 5. RIGHT JOIN(右外部結合) ```r right_result <- patients %>% right_join(weights, by = "id") ``` ``` > print(right_result) id name age weight_kg 1 1001 山田太郎 45 70 2 1002 田中花子 32 52 3 1003 佐藤次郎 67 82 4 1005 高橋健太 51 55 5 1006 <NA> NA 75 ``` RIGHT JOINは右のテーブル(weights)のすべてのレコードを保持します。id 1006は患者データがないため、nameとageにはNAが入ります。 ### 6. FULL JOIN(完全外部結合) ```r full_result <- patients %>% full_join(weights, by = "id") ``` ``` > print(full_result) id name age weight_kg 1 1001 山田太郎 45 70 2 1002 田中花子 32 52 3 1003 佐藤次郎 67 82 4 1004 鈴木美咲 28 NA 5 1005 高橋健太 51 55 6 1006 <NA> NA 75 ``` FULL JOINは両方のテーブルのすべてのレコードを保持します。id 1004とid 1006の両方が含まれ、欠損している部分にはNAが入ります。 ## まとめ RのtidyverseパッケージでのJOIN操作は、SQLの対応する操作と非常に似ており、直感的に理解できます。データ分析の現場では、データの欠損パターンや分析の目的に応じて適切なJOIN方法を選択することが重要です。 - **INNER JOIN**: 完全なデータペアのみが必要な場合 - **LEFT JOIN**: 主テーブルのすべてのレコードを保持したい場合 - **RIGHT JOIN**: 副テーブルのすべてのレコードを保持したい場合 - **FULL JOIN**: 両方のテーブルのすべての情報を保持したい場合 実際の医療データ分析では、患者の基本情報と検査結果、投薬記録などを結合する際に、これらの操作を頻繁に使用します。