Emails \(\hspace{0.6cm}:\) 1. hodawya125@gmail.com
\(\hspace{1.9cm}\) 2. juenzy.hodawya@matanauniversity.ac.id
Instagram \(\hspace{0.03cm}:\) https://www.instagram.com/j.hodawya/
Linked In \(\hspace{0.2cm}:\) https://www.linkedin.com/in/juenzy-hodawya-a310ab1a3/
RPubs \(\hspace{0.67cm}:\) https://rpubs.com/JHodawya
Kaggle \(\hspace{0.6cm}:\) https://www.kaggle.com/juenzyhodawya
GitHub \(\hspace{0.52cm}:\) https://github.com/JuenzyHodawya
Pada bagian terakhir Bagian 2 kita telah membahas tentang pengenalan konsep dan metode analisis survival. Di sini, kita akan fokus pada Analisis Risiko yang Bersaing (Competing Risk Analysis) dengan memilih model dan menilai kecukupan (adequacy) dan kesesuaiannya. Package utama untuk digunakan dalam analisis risiko yang bersaing ini adalah cmprsk
.
Ketika subjek memiliki beberapa kemungkinan kejadian dalam pengaturan waktu ke peristiwa.
Contoh:
Semua atau sebagian dari ini (di antara yang lain) mungkin merupakan peristiwa yang mungkin terjadi dalam pembelajaran tertentu.
Ketergantungan yang tidak teramati di antara waktu kejadian adalah masalah mendasar yang mengarah pada kebutuhan akan pertimbangan khusus. Sebagai contoh, dapat dibayangkan bahwa pasien yang kambuh lebih besar kemungkinannya meninggal, dan oleh karena itu waktu untuk kambuh dan waktu kematian merupakan kejadian yang dependen.
Dua pendekatan analisis dengan adanya beberapa hasil potensial:
\(\hspace{0.5cm}\) 1. Penyebab spesifik hazard dari peristiwa tertentu: ini mewakili tarif per unit waktu peristiwa di antara mereka yang tidak gagal dari peristiwa lain.
\(\hspace{0.5cm}\) 2. Kejadian kumulatif peristiwa tertentu: ini menunjukkan tarif per unit waktu peristiwa serta pengaruh peristiwa yang bersaing.
Masing-masing pendekatan ini hanya dapat menerangi satu aspek penting dari data, sementara kemungkinan akan mengaburkan yang lainnya, dan pendekatan yang dipilih harus bergantung pada pertanyaan yang menarik.
Saat kita mengerjakan Analisis Risiko yang Bersaing, beberapa catatan tambahan dan referensi berikut ini harus kita pertimbangkan:
Beberapa referensi yang dapat kita gunakan sebagai pembelajaran lebih lanjut:
Kita menggunakan data Melanoma
dari package MASS
untuk mengilustrasikan konsep ini. Ini berisi variabel:
time
waktu bertahan hidup dalam beberapa hari, mungkin akan terjadi sensor.status
1 = meninggal karena melanoma, 2 = hidup, 3 = meninggal karena sebab lain.sex
1 = pria, 0 = wanita.age
umur dalam tahun.year
tahun beroperasi.thickness
ketebalan tumor dalam mm.ulcer
1 = kehadiran, 0 = tidak hadir.Perkirakan kejadian kumulatif dalam konteks risiko yang bersaing menggunakan fungsi cuminc
.
Catatan: dalam data Melanoma
, pasien yang terjadi sensor diberi kode sebagai 2
untuk status
, jadi kita tidak dapat menggunakan opsi cencode
default 0.
## Estimates and Variances:
## $est
## 1000 2000 3000 4000 5000
## 1 1 0.12745714 0.23013963 0.30962017 0.3387175 0.3387175
## 1 3 0.03426709 0.05045644 0.05811143 0.1059471 0.1059471
##
## $var
## 1000 2000 3000 4000 5000
## 1 1 0.0005481186 0.0009001172 0.0013789328 0.001690760 0.001690760
## 1 3 0.0001628354 0.0002451319 0.0002998642 0.001040155 0.001040155
Membuat plot R
dasar dengan semua defaultnya.
Di dalam legend:
Kita juga dapat memplot kejadian kumulatif menggunakan fungsi ggscompetingrisks
dari package survminer
.
Dalam hal ini kita mendapatkan panel yang diberi label sesuai dengan grup, dan legend berlabel peristiwa, yang menunjukkan jenis kejadian untuk setiap baris.
Catatan
multiple_panels = FALSE
untuk membuat semua grup diplot pada satu panel.R
, sumbu y tidak mengarah ke 1 secara default, jadi Anda harus mengubahnya secara manual.Dalam cuminc
, pengujian Gray digunakan untuk pengujian antar-kelompok.
Sebagai contoh, bandingkan hasil Melanoma
menurut ulcer
, ada atau tidaknya ulserasi. Hasil tes dapat ditemukan di Tests
.
ci_ulcer <-
cuminc(
ftime = Melanoma$time,
fstatus = Melanoma$status,
group = Melanoma$ulcer,
cencode = 2
)
ci_ulcer[["Tests"]]
## stat pv df
## 1 26.120719 3.207240e-07 1
## 3 0.158662 6.903913e-01 1
Kita juga dapat memvisualisasikan atau memplot kejadian kumulatif menurut kelompok dengan menggunakan package ggcompetingrisks
:
ggcompetingrisks(
fit = ci_ulcer,
multiple_panels = FALSE,
xlab = "Days",
ylab = "Cumulative incidence of event",
title = "Death by ulceration",
ylim = c(0, 1)
)
Catatan Saya pribadi merasa fungsi ggcompetingrisks
masih kurang dalam penyesuaian, terutama dibandingkan dengan ggsurvplot
. Saya biasanya melakukan plotting sendiri, dengan pertama-tama merapikan dataset dari hasil fit cuminc
, kemudian memplot hasilnya. Lihat kode sumber untuk presentasi ini untuk rincian kode yang mendasari.
library(tidyverse)
ciplotdat <-
ci_ulcer %>%
list_modify("Tests" = NULL) %>%
map_df(`[`, c("time", "est"), .id = "id") %>%
mutate(id = recode(
id,
"0 1" = "Not ulcerated:Death melanoma",
"0 3" = "Not ulcerated:Death other causes",
"1 1" = "Ulcerated:Death melanoma",
"1 3" = "Ulcerated:Death other causes")
) %>%
separate(id, c("Ulceration", "Event"), ":")
ggplot(ciplotdat, aes(x = time, y = est, color = Ulceration)) +
geom_step(lwd = 1.2, aes(linetype = Event)) +
ylim(c(0, 1)) +
theme_classic() +
theme(plot.title = element_text(size = 14),
legend.title = element_blank(),
legend.position = "bottom") +
labs(x = "Days",
y = "Cumulative incidence",
title = "Death by ulceration status") +
annotate("text", x = 0, y = 1, hjust = 0,
label = paste0(
"Death melanoma p = ",
ifelse(ci_ulcer$Tests[1, 2] < .001,
"<.001",
round(ci_ulcer$Tests[1, 2], 3)))) +
annotate("text", x = 0, y = 0.92, hjust = 0,
label = paste0(
"Death other causes p = ",
ifelse(ci_ulcer$Tests[2, 2] < .001,
"<.001",
round(ci_ulcer$Tests[2, 2], 3))))
Seringkali hanya satu dari jenis kejadian yang menarik, meskipun kita masih ingin memperhitungkan kejadian yang bersaing. Dalam hal ini kejadian yang menarik dapat diplotkan sendiri. Sekali lagi, saya melakukan ini secara manual dengan terlebih dahulu merapikan data set dari hasil fit cuminc
, kemudian memplot hasilnya. Lihat kode sumber untuk presentasi ini untuk rincian kode yang mendasari.
ciplotdat1 <-
ci_ulcer %>%
list_modify("Tests" = NULL) %>%
map_df(`[`, c("time", "est"), .id = "id") %>%
filter(id %in% c("0 1", "1 1")) %>%
mutate(Ulceration = recode(
id,
"0 1" = "Not ulcerated",
"1 1" = "Ulcerated")
)
ggplot(ciplotdat1, aes(x = time, y = est, color = Ulceration)) +
geom_step(lwd = 1.2) +
ylim(c(0, 1)) +
theme_classic() +
theme(plot.title = element_text(size = 14),
legend.title = element_blank(),
legend.position = "bottom") +
labs(x = "Days",
y = "Cumulative incidence",
title = "Melanoma death by ulceration status") +
annotate("text", x = 0, y = 1, hjust = 0,
label = paste0(
"p-value = ",
ifelse(ci_ulcer$Tests[1, 2] < .001,
"<.001",
round(ci_ulcer$Tests[1, 2], 3))))
Anda mungkin ingin menambahkan jumlah tabel risiko ke plot kejadian kumulatif, dan yang saya ketahui tidak ada cara mudah untuk melakukan ini. Lihat kode sumber untuk presentasi ini untuk satu contoh (dengan permintaan yang terpopuler, kode sumber sekarang disertakan langsung di bawah untuk satu contoh yang spesifik)
R
, ggcompetingrisks
, atau ggplot
.mel_plot <-
ggplot(ciplotdat1, aes(x = time, y = est, color = Ulceration)) +
geom_step(lwd = 1.2) +
ylim(c(0, 1)) +
coord_cartesian(xlim = c(0, 5000)) +
scale_x_continuous(breaks = seq(0, 5000, 1000)) +
theme_classic() +
theme(plot.title = element_text(size = 14),
legend.title = element_blank(),
legend.position = "bottom") +
labs(x = "Days",
y = "Cumulative incidence",
title = "Melanoma death by ulceration status") +
annotate("text", x = 0, y = 1, hjust = 0,
label = paste0(
"p-value = ",
ifelse(ci_ulcer$Tests[1, 2] < .001,
"<.001",
round(ci_ulcer$Tests[1, 2], 3))))
ggsurvplot
menggunakan survfit
di mana semua peristiwa dihitung sebagai titik akhir gabungan tunggal,
mel_fit <- survfit(
Surv(time, ifelse(status != 2, 1, 0)) ~ ulcer,
data = Melanoma
)
num <- ggsurvplot(
fit = mel_fit,
risk.table = TRUE,
risk.table.y.text = FALSE,
ylab = "Days",
risk.table.fontsize = 3.2,
tables.theme = theme_survminer(font.main = 10),
title = "Test"
)
plot_grid
dari package cowplot
untuk ini,
tables.theme = theme_survminer (font.main = 10)
!cowplot::plot_grid(
mel_plot,
num$table + theme_cleantable(),
nrow = 2,
rel_heights = c(4, 1),
align = "v",
axis = "b"
)
Dua pendekatan:
coxph
)crr
)Katakanlah kita tertarik untuk melihat pengaruh usia dan jenis kelamin pada kematian akibat melanoma, dengan kematian akibat penyebab lain sebagai kejadian yang bersaing.
Catatan:
crr
membutuhkan spesifikasi kovariat sebagai matriksfailcode
, secara default hasil dikembalikan untukfailcode = 1
shr_fit <-
crr(
ftime = Melanoma$time,
fstatus = Melanoma$status,
cov1 = Melanoma[, c("sex", "age")],
cencode = 2
)
shr_fit
## convergence: TRUE
## coefficients:
## sex age
## 0.58840 0.01259
## standard errors:
## [1] 0.271800 0.009301
## two-sided p-values:
## sex age
## 0.03 0.18
Pada contoh sebelumnya, baik sex
danage
dikodekan sebagai variabel numerik. Fungsi crr
tidak dapat menangani variabel karakter secara alami, dan Anda akan mendapatkan error, jadi jika ada variabel karakter, kita harus membuat variabel dummy menggunakan model.matrix
.
# Membuat suatu contoh variabel karakter
chardat <-
Melanoma %>%
mutate(
sex_char = ifelse(sex == 0, "Male", "Female")
)
# Membuat variabel tiruan dengan model.matrix
# Kode [, -1] menghapus perpotongan
covs1 <- model.matrix(~ sex_char + age, data = chardat)[, -1]
# Sekarang kita dapat meneruskannya ke argumen cov1, dan ini akan berhasil
crr(
ftime = chardat$time,
fstatus = chardat$status,
cov1 = covs1,
cencode = 2
)
## convergence: TRUE
## coefficients:
## sex_charMale age
## -0.58840 0.01259
## standard errors:
## [1] 0.271800 0.009301
## two-sided p-values:
## sex_charMale age
## 0.03 0.18
crr
Hasil output dari crr
tidak didukung baik oleh broom::tidy()
atau gtsummary::tbl_regress()
untuk saat ini. Sebagai alternatif, coba Mvcrrres
dari paketezfun
saya.
HR (95% CI) | p-value | |
---|---|---|
sex | 1.8 (1.06, 3.07) | 0.03 |
age | 1.01 (0.99, 1.03) | 0.18 |
Menyensor semua subjek yang tidak memiliki kejadian yang diinginkan, dalam hal ini kematian akibat melanoma, dan menggunakan coxph
seperti sebelumnya. Jadi, pasien yang meninggal karena penyebab lain sekarang disensor untuk pendekatan penyebab spesifik hazard terhadap risiko yang bersaing.
Hasil dapat diformat dengan broom::tidy()
atau gtsummary::tbl_regress()
.
chr_fit <-
coxph(
Surv(time, ifelse(status == 1, 1, 0)) ~ sex + age,
data = Melanoma
)
broom::tidy(chr_fit, exp = TRUE) %>%
kable()
term | estimate | std.error | statistic | p.value |
---|---|---|---|---|
sex | 1.818949 | 0.2676386 | 2.235323 | 0.0253961 |
age | 1.016679 | 0.0086628 | 1.909514 | 0.0561958 |
Characteristic | HR1 | 95% CI1 | p-value |
---|---|---|---|
sex | 1.82 | 1.08, 3.07 | 0.025 |
age | 1.02 | 1.00, 1.03 | 0.056 |
1
HR = Hazard Ratio, CI = Confidence Interval
|