生存時間曲線つづき

同じデータでマルコフ連鎖モンテカルロ法MCMCで
サンプリング数を増やしてベイス推定してみました。

model = "
 data {
 int<lower=1> N;
 int<lower=1> T;
 int<lower=1, upper=T> Time[N];
 int<lower=0, upper=1> Cens[N];
 }
 parameters {
 real<lower=0> sigma_log_hazard;
 vector<upper=0>[T] log_hazard;
 }
 transformed parameters {
 vector[T] log_S;
 vector[T] log_f;
 log_S[1] = log1m_exp(log_hazard[1]);
 log_f[1] = log_hazard[1];
 for (t in 2:T) {
 log_S[t] = log_S[t-1] + log1m_exp(log_hazard[t]);
 log_f[t] = log_S[t-1] + log_hazard[t];
 }
 }
 model {
 sigma_log_hazard ~ cauchy(0, 1);
 log_hazard ~ cauchy(0, 10);
 for (t in 2:T) {
 log_hazard[t] ~ normal(log_hazard[t-1], sigma_log_hazard);
 }
 for (n in 1:N) {
 if (Cens[n] == 1) {
 target += log_f[Time[n]];
 }
 else {
 target += log_S[Time[n]];
 }
 }
 }
 generated quantities {
 vector[T] hazard;
 vector[T] S;
 hazard = exp(log_hazard);
 S = exp(log_S);
 }
 "

モデルは以上のようになります。2段階差分です。

treat0とtreat1で層別化して計算して、それぞれのHazardを計算して
カプランマイヤー曲線を作成していきます。

treats=c("0","1")
result = lapply(seq_along(treats), function(i){
 tr = treat1[treat1$treat == treats[i],]
 data_stan = list(N=nrow(tr), T=max(tr$days), Time=tr$days, Cens=tr$response)
 stan_fit = stan(model_code = model, data=data_stan,
 chains=4, iter=4000, warmup=2000, thin=1, seed=3,
 control=list(adapt_delta=0.8, max_treedepth=10)
 )
stan_fit
 })

結果を取り出します。

my_extract = function(x,name){
 tb = summary(x, probs=c(0.025,0.975),pars=name)$summary
 df = data.frame(tb[,c("mean","2.5%","97.5%"), drop=F])
 colnames(df) = c("mean","lower","upper")
 df
 }

 df_S =lapply(result,function(x){
 df = my_extract(x,"S")
 df$time = 1:nrow(df)
 df
 })

 df_h =lapply(result,function(x){
 df = my_extract(x,"hazard")
 df$time = 1:nrow(df)
 df
 })

df_h
df_s mean lower upper time
hazard[1] 0.2096954 0.08387344 0.3903780 1
hazard[2] 0.1712744 0.04802357 0.3230828 2
hazard[3] 0.1963125 0.06834335 0.3630519 3
hazard[4] 0.2472448 0.09101379 0.5131296 4

[[2]]
mean lower upper time
hazard[1] 0.3977416 0.23382685 0.5844687 1
hazard[2] 0.2559223 0.07873641 0.4477860 2
hazard[3] 0.3500685 0.15705598 0.5648722 3
hazard[4] 0.5894864 0.28229141 0.8904038 4

df_S
[[1]]
mean lower upper time
S[1] 0.7903046 0.6096220 0.9161266 1
S[2] 0.6570841 0.4491418 0.8388618 2
S[3] 0.5312813 0.3129014 0.7445881 3
S[4] 0.4032806 0.1953451 0.6344232 4

[[2]]
mean lower upper time
S[1] 0.6022584 0.41553132 0.7661732 1
S[2] 0.4489916 0.27340555 0.6331652 2
S[3] 0.2941656 0.14536261 0.4755628 3
S[4] 0.1210898 0.02779909 0.2673877 4

kphaz = kphaz.fit(time=treat1$days, status=treat1$response, strata=treat1$treat)
df_kphaz = lapply(1:2,function(i){
f = (kphaz$strata==i)
data.frame(time=kphaz$time[f],haz=kphaz$haz[f])
})

図示します。

 plot_S =ggplot() +
 geom_line(data=df_S[[2]],aes(x=time,y=mean),size=0.5,linetype=1) +
 geom_ribbon(data=df_S[[2]],aes(x=time,ymin=lower,ymax=upper),alpha=0.3,inherit.aes=F) +
 geom_line(data=df_S[[1]],aes(x=time,y=mean),size=0.5,linetype=2) +
 geom_ribbon(data=df_S[[1]],aes(x=time,ymin=lower,ymax=upper),alpha=0.3,inherit.aes=F)
 plot(plot_S)

画像1

第1日目から差があって広がらないし、狭まらないです。
95%ベイズ信用区間は重なっていて有意差はなさそうです。

この記事が気に入ったらサポートをしてみませんか?