Stanでベイジアンメタ分析(一対比較の固定効果モデル)

はじめに

Network Meta-Analysis for Decision-Making (Statistics in Practice)』は,ベイズ統計学ネットワークメタ分析を学ぶ上で良い本ですが,紹介されているコードがWinBUGSだったりします(これ以外の書籍もWinBUGSが多い)。Mac & Stanユーザーとしては,WinBUGSはきついので,第2章で紹介されている一対比較(つまりネットワークメタ分析ではない)データの固定効果モデルをStanコードに書き直してみました。

Network Meta-Analysis for Decision-Making (Statistics in Practice)

Network Meta-Analysis for Decision-Making (Statistics in Practice)

  • 作者: Sofia Dias,A. E. Ades,Nicky J. Welton,Jeroen P. Jansen,Alexander J. Sutton
  • 出版社/メーカー: Wiley
  • 発売日: 2018/03/19
  • メディア: ハードカバー
  • この商品を含むブログを見る

使用するパッケージ

以下のパッケージを使います。これら一式がインストールされたDockerfileも公開しているので,こちらの記事も参照ください。

library(rstan)
library(tidybayes)
library(tidyverse)
library(bayesplot)
library(loo)

データ

使用するのは,『Network Meta-Analysis for Decision-Making』の2章で紹介されている血栓溶解薬のデータです(Caldwell et la., 2005のデータ)。データセット全体の中からACC t-PA(治療0,今回はこれをコントロールにする)とPTCA(治療1)を比較した11の試験を使います。つまり,一対比較(Pairwise comparison)データです。

studyは研究のID,treatmentは治療の種類(0=ACC t-PA,1=PTCA),deadは死者数,sampleSizeはその治療に参加した患者数です。studyNameは第1著者の姓か研究プロジェクト名, studyYearは論文の出版年です。

Pairwise data for meta-analysis

以下のような感じのデータです。

# A tibble: 6 x 7
  study treatment  dead sampleSize treatmentName studyName studyYear
  <dbl>     <dbl> <dbl>      <dbl> <chr>         <chr>         <dbl>
1     1         0     3         55 Acc_tPA       Ribichini      1996
2     2         0    10         94 Acc_tPA       Garcia         1997
3     3         0    40        573 Acc_tPA       GUSTO-2        1997
4     4         0     5         75 Acc_tPA       Vermeer        1999
5     5         0     5         69 Acc_tPA       Schomig        2000
6     6         0     2         61 Acc_tPA       LeMay          2001

固定効果モデルのStanコード

まず,data{}ブロックにおいて,使用するデータの定義をしています。教科書は行列形式でdeadやsampleSizeを読み込む形式ですが,少し今後の拡張を考えると面倒です(WinBUGSでやりやすいこととStanでやりやすいことは微妙に違ったりします)。まずlong型のデータセットにしてから(上記のデータはすでにそうなっています),各列をStanに読み込ませます。

parameters{}ブロックでは,推定するパラメータとして,mu(各研究におけるベースライン=各研究での治療0の効果)とd01(治療0と治療1の差=治療0よりも治療1が優れるor劣る効果の大きさ)を準備しています。

model{}ブロックでは,死者数が二項分布に従うとして,死者数が,binomial_logit(試験の参加人数,死亡確率を構成する式)から生成されます。なお,死亡確率を構成する式は,治療が0の場合,はその試験のmuのみで,治療1の場合は,その試験のmuにd01を足したものになります。d01とmuの事前分布としては,幅のひろーい正規分布としました。

generated quantities{}ブロックでは,d01から治療0に対する治療1のオッズ比や有害の確率を計算したり,モデル比較用の対数尤度(log_lik)も計算しています。

Stan code of pairwise data using fixed effect mode ...

パラメータ推定

Stanコードが書けましたので,早速,コンパイル&サンプリングをします。

ld = length(study)
rstan_options(auto_write = TRUE)
options(mc.cores = parallel::detectCores())
options(max.print = 99999)
fit_fixed <- stan("netmeta_pairwise_fixed_effect.stan",data=list(ld = ld, nt = 2, ns = 11, study = study, treatment = treatment, dead = dead, sampleSize = sampleSize), chains = 4, iter = 5500, warmup = 500, thin = 1)

推定結果

結果を簡単に確認します。

print(fit_fixed,digit = 3)

見にくいので,一部の結果のみを示します。若干ズレはありますが,教科書とほぼ同じ推定値になりました(関心のあるパラメータのみ掲載)。Rhatやn_effからもサンプリングも問題なさそうです。

mean se_mea sd 2.5% 97.5% n_eff Rhat
d01 -0.2344 0.0009 0.1194 -0.4689 -0.0026 17330 0.9999
OR01 0.7967 0.0007 0.0954 0.6257 0.9974 17086 0.9999
Prob_harm 0.0236 0.0012 0.1520 0.0000 0.0000 17264 0.9999

なお,収束判定は以下のように可視化してもできます(コードのみで図は割愛します)。R hat,トレースプロット,自己相関,有効サンプルサイズの順番です。

stan_rhat(fit_fixed, pars = c("d01", "mu"))
stan_trace(fit_fixed, pars = c("d01", "mu"),inc_warmup=T)
stan_ac(fit_fixed, pars = c("d01", "mu"))
stan_ess(fit_fixed, pars = c("d01", "mu"))

治療0に対する治療1のオッズ比をプロットしてみます。ACC t-PAと比べて,PTCAが死亡率を下げることが分かりますね。

fit_fixed %>% 
  spread_draws(OR01) %>% 
  ggplot(aes(x = OR01)) +
  stat_density(fill = "gray75") +
  stat_pointintervalh(aes(y = -0.05), point_interval = mean_qi, .width = .95) +
  annotate("text", label = "mean, 95% quantile intervals", x = 1.1, y = -0.05, hjust = 0, vjust = 0.3) +
  xlim(0.5,1.45)+
  labs(x="Odds ratio")

f:id:cpp-laboratory:20181210073620p:plain

単体では意味がないですが,モデル比較をすることもあるかと思い,Stanコードでは対数尤度も計算をしています。以下のコードでWAICも算出できます。

log_like <- extract_log_lik(fit_fixed)
waic(log_like)

これで,メタ分析の基本形である固定効果モデルをStanで実行できました!