データ分析において、複数のテーブルを結合する操作は非常に重要です。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**: 両方のテーブルのすべての情報を保持したい場合
実際の医療データ分析では、患者の基本情報と検査結果、投薬記録などを結合する際に、これらの操作を頻繁に使用します。