RでKaplan-Meier曲線を描く方法

統計

こんにちは、eURO2023です!

趣味(?)でRstudioをしています。

Kaplan-Meier曲線を描く機会があったので、備忘録としてまとめておきます。

Warning

私は統計については我流で学んでいます。

R、Rstudioについても我流です。

その点はご承知おきいただき、「統計素人がなんとなく統計やってみた」という目で観ていただければ幸いです。

質問、批評大歓迎です。

医師が統計を学ぶ上で、絶対読んだほうがよい!と思われる書籍を上げておきます。

¥3,740 (2025/02/23 02:30時点 | Amazon調べ)

特に、新谷先生が執筆された「今日から使える医療統計」はおすすめです!

私は第一版を持っていますが、第二版が登場したようですね。

とても読みやすく、医療統計を始める上でも、論文の中身を理解する上でも非常に参考になります。

ある程度理解できるようになった今でも、よく読み返す本です。

「医療統計の基礎のキソ」は、更にわかりやすく、

「p値とはなにか?」

という超基本的な内容から、深く掘り下げてわかりやすく伝えてくれています!

第1巻から3巻までありますが、すぐに読めますよ。

下準備(パッケージの読み込み、架空データセットの作成)

今回は架空のデータセット”X”を用いて、説明していこうと思います。

架空のデータセットもRstudioで作ることが出来るんです!

架空データセット作成のためのRプロンプトを下記に示します。順に解説しますね。

必要なパッケージのインストール、読み込み

# まず今回使用するパッケージをインストールおよび出力しましょう。

“tibble”はRstudioを用いてデータ解析する場合にほぼ欠かせない“tidyverse”に含まれるパッケージとなります!

tidyverseは今後Rstudioでデータ解析していきたい方には必須のパッケージ群となりますので、是非インストールしてください。

ただ、私の場合、tidyverseをインストールするのにかなり苦労しました…

以前の記事でも書いたので、参考にしてください。

“survival”パッケージは、生存分析の計算を担当するパッケージです。

主な機能として、

survfit() → Kaplan-Meier生存曲線の計算
coxph() → Cox比例ハザード回帰
survreg() → ロジスティック回帰のようなパラメトリック生存モデル
Surv() → 生存時間データの扱い

などがあります。パッケージのインストールは、下記コマンドで可能です。

“survminer”パッケージは、生存分析の結果を「きれいに可視化」するためのパッケージです。

主な機能として、

ggsurvplot() → Kaplan-Meier曲線の美しいプロット
ggforest() → Cox回帰のハザード比をプロット
pairwise_survdiff() → 生存曲線のペアワイズ比較

などがあります。パッケージのインストールは、下記コマンドで可能です。

参考になる本

また、少し難しい内容ですが、ExcelやCSVデータの整理の仕方、データ記述に関するtipsが詳しくまとめられている本になります。特にRを”Rstudio”をプラットフォームとして使っていく場合には、持っておいて損はないと思います。

乱数データの固定(オプション)

さて、ランダムデータの作成をしましょう。

このランダムデータを作成したあとに、CSVファイルとして保存して何度も使う場合は良いのですが、いちいち保存するのが面倒くさい場合は、同じデータが再現されるように、乱数データを固定します。

この()内には、どの数字を入れても構いません。

架空データの作成

さて、架空データを作成してみましょう!

人数(n)は100名、変数として”drug_A”を使ったか否か(drug_A)、生存しているかどうか(survival)、生存期間(survival_month)、年齢(age)、性別(sex)、BMI(BMI)、ヘモグロビン値(Hb)およびPerformance status(PS)を用いることとします。

tibble()はdata.frame()の拡張版のようなものです。ChatGPT(無料版)では、以下のように説明されていました。

tidyverseと組み合わせて使う場合は、tibble()を用いるのが良さそうですね。

Xと入力することで、Xの中身を見ることができます。tibble()では大きいデータフレームでも一部のみしか表示されないので、Consoleを圧迫しないですみますね。

print(X)でも同様に表記されます。

より多くの行(rows)を表示したい場合には、下の方にも書かれているように、print(X, n=15)などのように入力してください。

ランダムに作成したXをCSVファイルに保存することもできます。

この”synthetic_patient_data.csv”には好きな文字を打ち込んでいただいて大丈夫です。

row.names = FALSEですが、これを入力しないと、デフォルトでrow.names = TRUEになります。

その場合、CSVファイルをRstudioに読み込んだ際、1列目に新たな列””, “1”, “2”, “3”…が新たに作成されてしまいます。

ですので、特に理由がなければrow.names = FALSEをつけておくと良いでしょう。

カプランマイヤー曲線の作成

生データでカプランマイヤー曲線を作成する場合

まず全体のRスクリプトを示します。

サバイバルオブジェクトの作成

Surv() は、 生存時間データ (time-to-event data) を扱うための関数です。

“生存時間”(time) と “イベントの発生有無”(event) を指定して、解析に適したデータ形式に変換してくれます。

survival パッケージ (library(survival)) に含まれています

X$survival_month → 生存期間(例: “何ヶ月生存したか”)
X$survival → 生存状態(例: 死亡 = 1 / 生存 = 0)


つまり、「患者ごとの生存期間と、死亡したかどうかの情報を1つのオブジェクトにまとめる」

という役割を果たします。

この関数、

のように、パイプ演算子をもちいてもうまくいきません。多少面倒くさいですが、X$survival_monthやX$survivalのように、その都度”データ”$”目的の列”という表記にしましょう。

($は、左にデータ、右に列を入力することで、”データ”内の”列”を意味します)

ちなみに、surv_objは新たに作成するデータセットの名前で、好きに変えていただいて構いません。

print()で、surv_objの中身を確認してみましょう。

30+ 30 52 25+ 16…と1例目から100例目まで続きます。

30+は、30ヶ月経過しイベント発生なし(生存中)

30は、30ヶ月目にイベント発生(死亡)

52は、52ヶ月目にイベント発生(死亡)

25+は、25ヶ月経過しイベント発生なし(生存中)

というように、それぞれの生存期間に、イベント発生有無のタグをつけて返してくれているんですね。

生存分析モデル (survival model) の構築

このコマンドは Kaplan-Meier 生存曲線 (Kaplan-Meier Survival Curve) を作成するための 生存分析モデル (survival model) を構築するものです。

survfit() は Kaplan-Meier 生存曲線 や Cox回帰モデル で生存確率を推定するための関数で、survival パッケージ (library(survival)) に含まれています。

survfit()に先程構築したSurv()オブジェクトを指定することで、生存確率を推定できます。

surv_obj → 生存時間とイベント情報をまとめたオブジェクト (Surv() で作成)
drug_A → 解析するグループ分けの変数(この場合は、drug_Aありなし)
data = X → データフレーム”X”を使用

つまり、このスクリプトによって

「drug_A の2群(0 = No Drug, 1 = Drug A)で Kaplan-Meier 生存曲線を比較する」

ことができます!

print(km_fit)で中身をみてみましょう。

ここからわかることは、

drug_Aなしは57名、イベント発生(死亡)は31名、生存期間中央値(median)は44ヶ月(95% CI:37-53)。

drug_Aありは43名、イベント発生(死亡)は23名、生存期間中央値(median)は40ヶ月(95% CI:26-NA)(NAは未到達)。

と、論文でもよく見る非常に大事な情報が満載であることがわかりますね!

Kaplan-Meier曲線を描こう!

このようにキレイなグラフを描くことができました!

ggplot2を用いたグラフ作成は、様々なサイトで紹介されているので、参考にしてみてください。

ブログの末尾に紹介しておきますね。

COX比例ハザードモデル

COX比例ハザードモデルの結果は、下記のように表示されます。

exp(coef)はHR、つまりハザード比のことです。

exp(coef) = 1.0855 → HR = 1.085

つまり、drug_A = 1 の患者は drug_A = 0 に比べて死亡リスクが 1.085 倍ということになります。


p値は、z Pr(>|z|)を参照します。p値 = 0.78です。

drug_A の影響は 統計的に有意ではないことになります。


信頼区間は lower .95とupper .95を参照します。信頼区間は0.6101 – 1.931となります。

信頼区間に1.0 を含むため、drug_Aの影響があるとは言えないことになります。


Wald testはWard検定とよばれるものです。Cox比例ハザードモデルの係数の有意性の評価に用いられます。

さいごに

# スクリプト全景

参考にしたブログ・HP

イラスト・画像元

コメント

タイトルとURLをコピーしました