# R - 複数変数から最初の非欠損値を取得する
## 問題設定
コホート研究などで、患者ごとに測定開始時点が異なる場合がある。例えば、ある患者は第1訪問時(x_v1)から測定が開始されるが、別の患者は第2訪問時(x_v2)から測定が開始される。このような状況で、各患者の最初の測定値(ベースライン値)を取得したい。
## サンプルデータ
以下のようなデータフレームを例にする。
```r
df <- data.frame(
  x_v1 = c(10, NA, 11, 8, NA),
  x_v2 = c(9, 2, 6, NA, NA),
  x_v3 = c(5, 8, 5, 3, 9)
)
```
| 行 | x_v1 | x_v2 | x_v3 | 求めたいbase_v |
|----|------|------|------|----------------|
| 1  | 10   | 9    | 5    | 10             |
| 2  | NA   | 2    | 8    | 2              |
| 3  | 11   | 6    | 5    | 11             |
| 4  | 8    | NA   | 3    | 8              |
| 5  | NA   | NA   | 9    | 9              |
各行について、x_v1, x_v2, x_v3の順で最初の非欠損値を取得する。
## 方法1: ベタな条件分岐
条件分岐を使って順番にNAを置換する方法。
```r
rm(list = ls())
df <- data.frame(
  x_v1 = c(10, NA, 11, 8, NA),
  x_v2 = c(9, 2, 6, NA, NA),
  x_v3 = c(5, 8, 5, 3, 9)
)
df$base_v <- df$x_v1
df$base_v[is.na(df$x_v1)] <- df$x_v2[is.na(df$x_v1)]
df$base_v[is.na(df$x_v1) & is.na(df$x_v2)] <- df$x_v3[is.na(df$x_v1) & is.na(df$x_v2)]
```
この方法では:
1. まずx_v1をbase_vにコピー
2. x_v1がNAの行については、x_v2で置き換え
3. x_v1とx_v2の両方がNAの行については、x_v3で置き換え
変数が増えると条件が複雑になり、コードが長くなる。
## 方法2: dplyrのcoalesce()関数
dplyrパッケージの`coalesce()`関数を使うと、より簡潔に書ける。
```r
rm(list = ls())
library(dplyr)
df <- data.frame(
  x_v1 = c(10, NA, 11, 8, NA),
  x_v2 = c(9, 2, 6, NA, NA),
  x_v3 = c(5, 8, 5, 3, 9)
)
df <- df %>%
  mutate(base_v = coalesce(x_v1, x_v2, x_v3))
```
`coalesce()`関数は、引数として渡された変数を左から順に評価し、最初の非NA値を返す。1行で処理が完了し、変数が増えても引数を追加するだけで対応できる。
## 実行結果
どちらの方法でも、以下の結果が得られる。
```r
print(df)
```
```
  x_v1 x_v2 x_v3 base_v
1   10    9    5     10
2   NA    2    8      2
3   11    6    5     11
4    8   NA    3      8
5   NA   NA    9      9
```
## まとめ
複数の変数から最初の非欠損値を取得する処理は、条件分岐でも実装できるが、`coalesce()`関数を使う方が:
- コードが短く読みやすい
- 変数が増えても対応しやすい
- 意図が明確
臨床研究のベースライン値設定など、実務でよく使用する処理のため、`coalesce()`の使い方を覚えておくと便利。