R歴1ヶ月の俺がtidyverseを使ってNDBオープンデータから尿蛋白検査の地域差を検証してみた件について #1

# R for Data Science 学習記録 #2

今回からしばらく、NDBオープンデータを用いた実践形式により、[R for Data Science](https://r4ds.had.co.nz/index.html) の勉強記録をつけていこうと思います。
データサイエンスのワークフローについてHadley Wickham氏は、以下のフレームにまとめています。
**Import→Tidy→(Transform→Visualize→Model)→Communicate**　※()内は繰り返す
- **Import**: データをRStudioに読み込む
- **Tidy**: データをtidy dataの形にする
- **Transform**: 新しい変数を作ったり、統計量を計算したりする
- **Visualize**: ggplot2などを用いてデータを可視化する
- **Model**: モデルを用いてデータを検証する
- **Communicate**: 分析結果を他人に伝える

その1では **Import** から **Tidy** まで行います。

## 使ったデータ
### [NDBオープンデータ](https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000177182.html)とは
- 「NDBは、電子化されたレセプト情報並びに特定健診・特定保健指導情報によって構成されている。 レセプトとは、保険診療を⾏った医療機関が、診療報酬点数表に基づいて診療報酬（医療費）を保険者に請求するために、患者⼀⼈につき毎⽉作成する診療報酬明細書のことである。特定健診は、 医療保険者（国⺠健康保険・被⽤者保険）のうち 40 歳以上 75 歳未満の被保険者・被扶養者を対象 とする内臓脂肪型肥満に着目した特定健診、いわゆるメタボ健診の受診情報が元となっている。特定保健指導は、特定健診の受診者のうち、一定の基準に該当する者に対して特定保健指導が実施さ れ、その際の保健指導に関する情報が元となっている。」 ([第3回NDBオープンデータ解説編](https://www.mhlw.go.jp/content/12400000/000346720.pdf)より抜粋)
- 日本の保険診療を受けた人全員のデータを根こそぎ集めたもの！

### 今回は特定健診のひとつ、尿蛋白検査のデータを使ってみました
- URL: https://www.mhlw.go.jp/content/12400000/000347819.xlsx
- 尿蛋白検査は腎臓の機能不全のサインとなる検査で、-, ±, +, ++, +++の5段階で評価されます。

## tidy化
### tidy dataとは
tidy dataはHadley Wickham氏が提唱した、データ駆動型の解析に適したデータ管理形式。
以下のルールに従う
	- 1列：1変数
	- 1行 :  1観測
	- 1セル : 1値
RのライブラリtidyverseはTidy Dataを扱うために最適化されている。
よってデータ前処理の最初の過程として、元データをtidy dataに加工する。

### 元はこんな感じ
![enter image description here](https://lh3.googleusercontent.com/8n7V51trUTVL6dlKSSNkl0r1vwLj0ZxNhqkQo7Ud6feNr1_zEKEhWG4gXLcrOZZa51rXLYPk11bw)
これをtidyしていきます

### どんな変数があるか
まず、tidyしたらどうなるかを考えるために、変数を整理していきましょう。
このデータには5つの変数があります。
- 性別: 男性/女性の2値変数
- 年齢: 40歳から74歳まで、5歳区切りにした7値のカテゴリ変数
- 都道府県: 47都道府県、47値のカテゴリ変数
- 検査結果: -, ±, +, ++, +++の5値のカテゴリ変数
- ケース数: 各変数の組み合わせを持つケース数。整数値をとる

ということは、2×7×47×5 = 3290の観測があるはずですから、tidy化した後は **3290 × 5**のデータになりますね。

### 何が問題か
R4DSには、messyなデータの問題として、変数や観測が複数行/列にまたがってしまっていることが挙げられています。この場合だと、
- 性別が複数列
- 年齢が性別のサブグループとして複数列
- 都道府県が複数行

にまたがってしまっています。

### Google spread sheet上での処理
勉強不足で申し訳ないのですが、このデータをtidyverseだけでtidyするのはきついです。
なので、ある程度spread sheet上で処理してしまいます。
- 都道府県のセルの結合を外し、各観測に合わせる
- 検査結果を1~5の数字に変換する
- 都道府県と検査結果に変数名Prefecture, Testを付ける
- 変数Sexを表す列を追加し、男女(M, Fで表す)を各観測に対応させる
- 年齢について、グループの中央値で代表させた列名をつける

これらの操作を行った結果が以下の通りです。
![enter image description here](https://lh3.googleusercontent.com/nBsA1Qju5avmbFaJsHHE1ACmdlnObXn4kzyAYOelDZoQgK-cil972sa3W3Ovn6jt1FAyw-1zWZmY)
流石に年齢までマウスでやるのは大変なのでここからはtidyverseの出番です。
csv形式("UrineProtein_pretidy.csv")でdownloadします。
tidy一歩手前ということでpretidyと命名します。

### tidyverseによるtidy化
ここからRStudioでの作業に入ります。
まずはtidyverseの読み込みとcsvファイルのimportから。

    library(tidyverse)
    pretidy <- read_csv("UrineProtein_pretidy.csv")
-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
�� ggplot2 3.0.0     �� purrr   0.2.5
�� tibble  1.4.2     �� dplyr   0.7.6
�� tidyr   0.8.1     �� stringr 1.3.1
�� readr   1.1.1     �� forcats 0.3.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
Parsed with column specification:
cols(
  Prefecture = col_character(),
  Sex = col_character(),
  Test = col_integer(),
  `42` = col_character(),
  `47` = col_character(),
  `52` = col_character(),
  `57` = col_character(),
  `62` = col_character(),
  `67` = col_character(),
  `72` = col_character()
)

これをtidy化するには**gather()**メソッドを使います。
**gather(data, (集約したい列名), key = "集約後の変数名", value = "値を格納する変数名")**

    tidy <- gather(pretidy, "42", "47", "52", "57", "62", "67", "72", key = "Age", value = "Cases")
   ![enter image description here](https://lh3.googleusercontent.com/WZ3pvAtsoG8V16tVhwmWAys8m4HC83VYAyV7-eE1N3CCkQk8JBshpVl-dvS7bMLzqY5MKSxsvE3a)
   tidy化されたtibble、**tidy**　が作られました。最初の読み通り、**3290×5**の配列になっていますね。

## まとめ
tidyverseのメソッド **gather()**を用いることでデータをtidy化することができました。
今回は2変数が複数列にまたがってしまっていたため、表計算ソフト上での作業も必要になってしまいました。
> Written with [StackEdit](https://stackedit.io/).