タグ:tableone

前回は今までの総復習を行いました。
【演習】R初心者が統計をかけるための前準備の流れを復習します : 独学で始める統計×データサイエンス



上記の記事を進めると以下のように統計量をまとめて出すことができますが、summary関数では標準偏差が出ません。
スクリーンショット 2019-02-04 21.49.17


今回は標準偏差を出すいろいろな方法を復習も含め紹介します。

繰り返しのfor関数やapply関数、パイプ演算子(%>%)もはじめて出てきますが、使えるようになるとFIMのような項目が多いものでも1度にまとめて解析できるようになり、いよいよExcelではできない体験をすることができるようになります。

まだ今回の内容であればExcelでも可能ですが、1つずつ進めていきましょう。

1.sd関数で1つずつ出す
2.for関数で繰り返す
3.apply関数を使う
4.tableoneパッケージを使う


今回は前回の記事のデータを使います。

data01.xlsx 

ダウンロードした後、プロジェクトの指定フォルダにファイルを移動させておけば、以下のコマンドで上記の画面まで進みます。

library(readxl)
data01 <- read_excel("data01.xlsx", sheet = "日本語")
data01$性別 <- factor(data01$性別, levels = c("男性","女性"))
data01$歩行 <- as.factor(data01$歩行)
summary(data01)

*注意
もしプロジェクトファイルを作成していない場合はgetwd()と打ち込むと作業フォルダが表示されます、作業フォルダにExcelデータを入れると後は同じです。

getwd()




1.sd関数で1つずつ出す

標準偏差を出す関数はsd関数です。

sd(ベクトル)
sd(data01[[3]])
sd(data01[[4]])
sd(data01[[5]])
sd(data01[[6]])
sd(data01[[7]])
sd(data01[[8]])
スクリーンショット 2019-02-04 21.53.36


data.frameからベクトルを表示するには$または[[ ]]を使います。
[[ ]]の中の数字は列番号です。
$でもいいのですが、このようなケースでは列番号のほうが手っ取り早いです。

列番号を確認するにはnames関数t関数(もしくはdata.frame関数)を使うと便利です。

t(names(data01))
スクリーンショット 2019-02-04 23.20.52

data.frame(names(data01))
スクリーンショット 2019-02-04 23.22.06


2.for関数で繰り返す

1個ずつ出すのもいいですが、繰り返しになる作業はfor関数で繰り返すことができます。
for(i in 3:8){
  x <- sd(data01[[i]])
  print(x)
  }

for関数は(◯ in △)と{}の2つに別れています。
スクリーンショット 2019-02-04 23.51.05
スクリーンショット 2019-02-04 23.59.46


スクリーンショット 2019-02-05 0.03.59

ただ結果は出るのですが結果の数字しか出ません。


3-1.apply関数を使う

library(tidyverse)
apply(data01, 2, sd)

スクリーンショット 2019-02-05 0.17.43

スクリーンショット 2019-02-05 0.08.54


下にエラーが出ます。これは「氏名と性別で集計できないからNAにしてますよ!」と怒られています。なのでselect関数で集計する列だけ抜き出します。


library(tidyverse) #既に実行していたらなくても可
data01_select <- select(data01, 3:8) data01_select apply(data01_select, 2, sd)
スクリーンショット 2019-02-05 0.32.27

今回はdata01_selectという変数名にselect関数で3〜8列目だけ抜き出しapply関数を使いました。


スクリーンショット 2019-02-05 0.33.14


ただこの方法はdata01_selectのように間に変数を挟む必要があります。
tidyverseパッケージはこれをスッキリさせるパイプ演算子(%>%)というものがあります。


3−2.パイプ演算子を使ったapply関数

パイプ演算子(%>%)は解析の流れをスムーズにしてくれます。

データ① %>%
    プログラム② %>%
    プログラム③ %>%
    プログラム④

とすると先程のdata01_selectの用な変数を介することもなく、データ①をプログラム②に送り、その結果をプログラム③に送り、その結果をプログラム④に送るといったことが可能になります

library(tidyverse) #既に実行していたらなくても可
data01 %>% #data01に対して
  select(3:8) %>% #3列目(年齢)〜8列目(MMSE)までを選択し
  apply(., 2, sd) #それぞれの列で標準偏差を求めて!

スクリーンショット 2019-02-05 0.55.55
スクリーンショット 2019-02-05 0.57.27


もし四捨五入するならround関数を使います。

library(tidyverse)#既に実行していたらなくても可
data01 %>% #data01に対して
  select(3:8) %>% #3列目(年齢)〜8列目(MMSE)までを選択し
  apply(., 2, sd) %>% #それぞれの列で標準偏差を求めて!
  round(.,2) #小数点2位より下を四捨五入する
スクリーンショット 2019-02-05 1.13.08


4.tableoneパッケージを使う

tableoneパッケージを使うのも1つの方法です。

tableoneパッケージについてはこの記事で紹介しています。
Rで医療統計で必要なtable1を作るtableoneパッケージについて紹介します : 独学で始める統計×データサイエンス

library(tableone)
CreateTableOne(data = data01,
               vars = c("年齢", "身長", "体重", "SIAS", "BBS", "MMSE"))
スクリーンショット 2019-02-05 1.20.05


まとめ

今回は標準偏差を出すいろいろな方法を通じてfor関数やapply関数、パイプ演算子の使い方を紹介しました。

今回は標準偏差(sd)でしたが、平均(mean)や中央値(median)など他の統計量も求めることができます。

for関数やtidyverse(dplyrなど)に関してはまとまった記事もありますが、これからもちょくちょく出てくると思います。その都度復習しながら使い方のイメージを付けていただければいいかと思います。








医療統計でよく出てくるtable1について質問がありました。





ということで今回は医療統計で使われるtable1を作る時に便利なtableoneパッケージについて紹介します。


以下に今回使う仮のデータを作りました。set.seed(1)とかfloor()とかsampleとか訳のわからないものがいっぱい出てきますが、とりあえずRに全部コピーして1行ずつ実行するとdataという名前の表が完成します。(もしくはスクリプトウィンドウにコピペして全部選択した状態でRunを押してください)

set.seed(1)
年齢 <- floor(rnorm(100,60,10))
性別 <- sample(c("男性","女性"),100,replace = TRUE)
体重 <- floor(rnorm(100,60,7))
MMT <- sample(c(1:5), 100, prob = c(0.1,0.1,0.2,0.3,0.3), replace = TRUE)
術側 <- sample(c("右","左"),100,replace = TRUE)
治療 <- sample(c(0,1),100,replace = TRUE)
data <- data.frame(年齢,性別,体重,MMT,術側,治療)
data


tableoneの使い方

0.tableoneパッケージを使えるようにする

1.事前に理解しておくこと

2.CreateTableOne関数でtable1の下地を作る

3.print関数でExcelに貼り付けるための形式に直す

4.Excelでインポート

5.できるだけプログラムを書きたくない人向けの方法



0.tableoneパッケージを使えるようにする

まずはtableoneパッケージを使えるように準備をしてください。

なおパッケージの導入方法については以下の記事で解説しています。
Rで使うパッケージのインストールについて紹介します。 : 独学で始める統計×データサイエンス



1.事前に理解しておくこと


table1はそもそも各群のベースラインを比較します。

スクリーンショット 2019-01-29 13.41.06
そのためには各変数(評価)がどんなデータか理解している必要があります


数値かカテゴリーか?

集計を行うにはその変数が数値なのか?カテゴリー変数なのか?の理解が必要です。

数値:年齢・体重

カテゴリー:性別、MMT、術側

MMTは「1が7人、2が5人・・・」と集計を行いたいとすると、値は数値ですがカテゴリー変数として集計を行う必要があります。


数値の場合は正規分布なのか?そうでないのか?

同じ数値でも正規分布かそうでないのか?を決めておくことが必要です。

正規分布であれば平均±標準偏差ですが、正規分布でない場合は中央値(四分位範囲 or 最大値〜最小値)で表現したりします。

正規分布かどうかを確認するにはヒストグラムやQ-Qplotを作成したり、シャピロ-ウィルクの正規性の検定を使ったりします。


カテゴリー変数の検定はカイ二乗検定なのかFisherの正確確率検定なのか?

カテゴリー変数の場合カイ二乗検定かFisherの正確確率検定なのかを決めておくことが必要です。

データ数が少なく各期待数が5未満だとFisherの正確確率検定を使うなどありますが、詳細は今後説明していくかもしれません。


以上を踏まえた上でtableoneパッケージを使っていきます。


2.CreateTableOne関数でtable1の下地を作る

table1の下地を作るにはCreateTableOne関数を使います。

コード(1行で書く場合)
スクリーンショット 2019-01-29 17.43.23

コード(複数行に渡って書く場合。要素の間の , を忘れずに)
スクリーンショット 2019-01-29 17.30.54

t1を表示して結果を見ます
スクリーンショット 2019-01-29 17.49.04


結果
スクリーンショット 2019-01-29 17.31.09

コード(コピペ用)
t1 <- CreateTableOne(data = data, 
                     vars = c("年齢", "性別", "体重", "MMT", "術側"), 
                     factorVars = "MMT", 
                     strata = "治療")
t1


コードはスクリプトウィンドウを使うと数行にまたがって書くことができます。


(スクリプトウィンドウについてはRコマンダーの基本的な画面の説明を行いますをご参照ください。)


CreateTableOne関数には主に4つの要素があります。


data = ○○

○○には今回使用する表の変数名が入ります。

今回は「data」という名前の表を作ったのでdataになっていますが、別の名前を使った時はその名前になります。大文字と小文字は区別しますので注意。



vars = "○○"

○○には表に乗せたい変数名を並べます。

複数の変数がある場合はc("変数名1", "変数名2")とc関数を使います。

変数名が1つなら vars = "変数名"

変数を" "ではさみ、を使って区切ってください。


factorVars = "○○"

vars = "○○"の中で「数値なんだけどカテゴリー変数」というものがあればfactorVarsに加えます。

今回でいうとMMTの1〜5の値です。

性別や術側のように数値でないカテゴリー変数は自動的にカテゴリー変数とみなしてくれるので、ここに入れるのはあくまでも「数値なんだけどカテゴリー変数」だけです。

ちなみにそういう変数がなければfactorVars = "○○"自体を消してしまってOKです。


strata = "○○"

今回の治療のように分けたいグループがここに入ります

またグループ間ごとの検定を行うこともできます。

2グループならt検定とマンホイットニーのU検定、3グループ以上なら一元配置分散分析とクラスカル=ウォリス検定を行います。

もしstrata = "○○"自体を消すとグループ分けせずに全体の要約が表示されます。

コード
スクリーンショット 2019-01-29 17.55.31
結果
スクリーンショット 2019-01-29 17.55.44



3.print関数でExcelに貼り付けるための形式に直す

これでもある程度表になっているのですが、もう一つ作業が残っています。

まだ「正規分布かそうでないか?」「見た目をもう少し修正」といったところです。

ここではprint関数を使います。

今度はtable1という変数を使います。違う名前でも構いません。


コード
スクリーンショット 2019-01-29 20.09.46


コード(コピペ用)
table1 <- print(x = t1, 
                cramVars = c("性別", "術側"),
                exact = "MMT",
                nonnormal = "体重")

write.csv(table1,"table1.csv")        

print関数にもいくつかの要素があります。

x = ○○

xには先程のcreateTableOne関数の結果を入れます。

先ほどで言う「t1」です。違う名前にした方はその名前にしてください。

" "はいりません。


cramVars = "○○"

改めてt1の性別や術側の項目を見てください。

スクリーンショット 2019-01-29 20.15.45

基本設定では2つのカテゴリーの場合、1つの要素しか出してくれません。
もちろん全体数から引けばいいといえばいいのですが、女性の数も欲しいところです。

そんな時cramVars = c("性別", "術側")を入れると以下のようになります。

スクリーンショット 2019-01-29 20.22.43


exact = "○○"

カテゴリー変数の検定は何も指定しないとカイ二乗検定を行います。

もしFisherの正確確率検定を使いたい場合(ここではMMTとする)、exact = "MMT"とします。

ちゃんとなっているかどうかは一番右のtestを見ます。exactとなっています。

nonnormal = "○○"

同じ数字でも正規分布に従わないデータがある場合は中央値(四分位範囲)で示します。

たとえば今回のデータで体重が正規分布でなかったとします。

その場合はnonnormal="体重"とすることで平均(標準偏差)ではなく中央値(四分位範囲)に変えることができます。

ちなみに四分位範囲でなく(最小値〜最大値)で表現したい場合はminMax= TRUEを付け加えます。

スクリーンショット 2019-01-29 20.35.02


write.csv(○○, "保存したい名前.csv")

table1で表示したい表を作成したあとはcsv形式で保存します。

csv形式で保存するにはwrite.csv関数を使います。

○○はprint関数で使った変数名(ここではtable1)です。

" "の中はファイル名.csvとします。


プロジェクトを作っているとfileビューでファイルを確認できます。

スクリーンショット 2019-01-29 20.59.49

もしプロジェクトを作っていなくて保存場所がわからない場合はgetwt()とコードを書き実行してください。

getwt()     

()の中は何も入れなくて大丈夫です。保存先がわかります。


4.Excelでインポート

csvファイルを作成したので、今度はExcelで読み込みます。

読み込む時はインポートを使います。

スクリーンショット 2019-01-29 13.34.04


csvファイルを選択します。

スクリーンショット 2019-01-29 13.34.54


先程作成したファイルを選択します。
スクリーンショット 2019-01-29 13.35.23


macだと文字化けします。UFT-8を選択します。

スクリーンショット 2019-01-29 13.38.09



フィールドの区切りはカンマを選択します。

スクリーンショット 2019-01-29 13.38.35


ここは特に何もせず完了します。

スクリーンショット 2019-01-29 13.38.51


貼り付ける場所を選択します。

スクリーンショット 2019-01-29 13.39.09


無事完成!
スクリーンショット 2019-01-29 21.13.01



5.できるだけプログラムを書きたくない人向けの方法


慣れると早くなるのですが、どうしてもまだ慣れないということもあると思います。

2つの方法を紹介します。


①createTableOne関数の後、printを行わずデータを直接見ながらExcelに手打ちする

print関数を使わずにsumarry関数を使います。

スクリーンショット 2019-01-29 21.16.49
スクリーンショット 2019-01-29 21.17.02
スクリーンショット 2019-01-29 21.17.21

ここにグループ毎の結果が入っています。

<数値の場合>
平均(mean)
標準偏差(sd)
中央値(median)
最小値(min)
最大値(max)

t検定か一元配置分散分析(pNormal)
マンホイットニーのU検定かクラスカル=ウォリス検定(pNonNormal)

標準化平均差(Standardize mean differences)


<カテゴリーの場合>
カテゴリー名(level)
各変数の数(freq)
各変数の%(percent)
累積%(cum.percent)

カイ二乗検定(pApprox)
Fisherの正確確率検定(pExact)


これらを見て直接Excelに打ち込んでもいいかもしれません。


②EZRを使う

EZRの「サンプルの背景データのサマリー表の出力」は実はtableone関数を使っています。

スクリーンショット 2019-01-29 21.36.32

今回の記事を見た上でこの画面を見て、どの項目がどの関数を使っているかイメージできるでしょうか。


まとめ

今回はRやプログラミングに慣れていない方でもイメージできるよう、tableone関数についてできるだけ細かく解説しました。

学会や論文の作成のサポートになれば幸いです。


↑このページのトップヘ