Email: abigaylerachman2009@gmail.com
RPubs: https://rpubs.com/abgylrchmn/
Pada bagian terakhir Bagian 2 kita telah membahas tentang pengenalan konsep dan metode analisis kelangsungan hidup. Di sini, kita akan fokus pada Competing Risk Analysis (CRA) dengan memilih model dan menilai kecukupan dan kecocokannya. Package utama yang akan digunakan dalam materi ini adalah cmprsk, selain itu ada juga beberapa package yang kita butuhkan seperti berikut :
## Loading required package: survival
## Loading required package: ggplot2
## Loading required package: ggpubr
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v tibble 3.0.4 v dplyr 1.0.2
## v tidyr 1.1.2 v stringr 1.4.0
## v readr 1.4.0 v forcats 0.5.0
## v purrr 0.3.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
Ketika suatu subjek yang kita teliti memiliki beberapa kejadian yang mungkin terjadi di a time to event setting.
Contoh : - kambuhnya suatu penyakit - kematian dari suatu penyakit - kematian akibat suatu kejadian lain selain penyakit - respon dari perawatan yang sedang dijalani, seperti kemo dll
Semua contoh diatas dan yang lainnya bisa jadi merupakan peristiwa yang mungkin terjadi dalam kasus atau pembelajaran tertentu.
Ketergantungan yang tidak teramati di antara waktu peristiwa adalah masalah mendasar yang mengarah pada kebutuhan akan pertimbangan khusus. Sebagai contoh, dapat dibayangkan bahwa pasien yang kambuh lebih mungkin meninggal, dan oleh karena itu waktu untuk kambuh dan waktu kematian bukanlah kejadian yang independen.
CRA di latar belakangi dengan adanya dua pendekatan analisis yang memiliki beberapa hasil potensial :
-Bahaya penyebab khusus dari peristiwa tertentu: ini mewakili tingkat per unit waktu peristiwa di antara mereka yang tidak gagal dari peristiwa lain -Insiden kumulatif dari acara tertentu: ini mewakili rasio per unit waktu acara serta pengaruh acara yang bersaing Masing-masing pendekatan ini hanya dapat menerangi satu aspek penting dari data sementara mungkin mengaburkan yang lain, dan pendekatan yang dipilih harus bergantung pada pertanyaan yang menarik.
Saat kami mengerjakan Analisis Risiko Bersaing, berikut beberapa catatan dan referensi tambahan yang harus kami pertimbangkan:
Ketika kejadiannya independen (hampir tidak pernah benar), bahaya spesifik penyebab tidak bias
Saat kejadian bergantung, berbagai hasil dapat diperoleh bergantung pada pengaturan
Insiden kumulatif menggunakan Kaplan-Meier selalu> = insiden kumulatif menggunakan metode risiko yang bersaing, sehingga hanya dapat menyebabkan perkiraan berlebih dari insiden kumulatif, jumlah perkiraan yang terlalu tinggi tergantung pada tingkat kejadian dan ketergantungan antar kejadian
Untuk menetapkan bahwa kovariat memang bekerja pada peristiwa yang diinginkan, bahaya spesifik penyebab mungkin lebih disukai untuk pengobatan atau pengujian efek penanda pronostik
Untuk menetapkan manfaat secara keseluruhan, bahaya subdistribusi mungkin lebih disukai untuk membangun nomogram prognostik atau mempertimbangkan efek ekonomi kesehatan untuk mendapatkan pemahaman yang lebih baik tentang pengaruh pengobatan dan kovariat lainnya pada skala absolut
Beberapa referensi yang bisa kita dekati untuk mempelajari lebih lanjut:
Dignam JJ, Zhang Q, Kocherginsky M. The use and interpretation of competing risks regression models. Clin Cancer Res. 2012;18(8):2301-8.
Kim HT. Cumulative incidence in competing risks data and competing risks regression analysis. Clin Cancer Res. 2007 Jan 15;13(2 Pt 1):559-65.
Satagopan JM, Ben-Porat L, Berwick M, Robson M, Kutler D, Auerbach AD. A note on competing risks in survival data analysis. Br J Cancer. 2004;91(7):1229-35.
Austin, P., & Fine, J. (2017). Practical recommendations for reporting Fine‐Gray model analyses for competing risk data. Statistics in Medicine, 36(27), 4391-4400.
Estimasi non-parametrik dari insiden kumulatif Memperkirakan insiden kumulatif acara yang diminati Kapan pun jumlah insiden kumulatif setiap peristiwa sama dengan total insiden kumulatif peristiwa apa pun (tidak benar dalam pengaturan khusus penyebab) Tes Gray adalah tes Chi-squared yang dimodifikasi yang digunakan untuk membandingkan 2 atau lebih kelompok
Kami menggunakan data Melanoma dari paket MASS untuk menggambarkan konsep ini. Ini berisi variabel:
time survival time in days, possibly censored. status 1 died from melanoma, 2 alive, 3 dead from other causes. sex 1 = male, 0 = female. age age in years. year of operation. thickness tumor thickness in mm. ulcer 1 = presence, 0 = absence.
Perkirakan insiden kumulatif dalam konteks risiko bersaing menggunakan fungsi kumulatif.
Catatan: dalam data Melanoma, pasien yang disensor diberi kode 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
Hasilkan plot R dasar dengan semua default.
Keterangan :
Angka pertama menunjukkan kelompok, dalam hal ini hanya ada perkiraan keseluruhan jadi 1 untuk keduanya Angka kedua menunjukkan jenis kejadian, dalam hal ini garis padat adalah 1 untuk kematian akibat melanoma dan garis putus-putus adalah 3 untuk kematian akibat penyebab lain Kami juga dapat memplot insiden kumulatif menggunakan fungsi ggscompetingrisks dari paket survminer.
Dalam hal ini kita mendapatkan panel yang diberi label sesuai dengan grup, dan legenda berlabel peristiwa, yang menunjukkan jenis peristiwa untuk setiap baris.
Catatan
Anda dapat menggunakan opsi multiple_panels = FALSE untuk membuat semua grup diplot pada satu panel tidak seperti basis R, sumbu y tidak pergi ke 1 secara default, jadi Anda harus mengubahnya secara manual
Dalam tes cuminc Gray digunakan untuk tes antar-kelompok.
Sebagai contoh, bandingkan hasil Melanoma menurut ulkus, ada atau tidaknya ulserasi. Hasil tes dapat ditemukan di Tes.
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
Kami juga dapat memvisualisasikan atau memplot insiden kumulatif menurut kelompok dengan menggunakan paket ‘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 menemukan fungsi ggcompetingrisks kurang dalam penyesuaian, terutama dibandingkan dengan ggsurvplot. Saya biasanya melakukan plotting saya sendiri, dengan terlebih dahulu membuat dataset yang rapi dari hasil cuminc fit, dan 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)
Dapatkan plot dari basis 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))))Dapatkan nomor pada tabel risiko dari ggsurvplot menggunakan survfit di mana semua peristiwa dihitung sebagai titik akhir gabungan tunggal, Paksa sumbu memiliki batas dan jeda dan judul yang sama,
pastikan warna/linetypes cocok dengan label grup,
Cobalah untuk mendapatkan ukuran font yang sama.
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"
)## Warning: Vectorized input to `element_text()` is not officially supported.
## Results may be unexpected or may change in future versions of ggplot2.
Kemudian gabungkan plot dan risktable. Saya menggunakan fungsi plot_grid dari package cowplot untuk ini, Terima kasih kepada beberapa pembaca yang telah mengirimkan saya email berisi tip tentang cara mengubah ukuran teks yang bertuliskan “Jumlah berisiko”! Saya menggunakan yang disarankan oleh Charles Champeaux, diimplementasikan di atas di baris 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:
Penyebab spesifik hazard tingkat kejadian seketika dari jenis peristiwa tertentu dalam subjek yang saat ini tidak terjadi suatu peristiwa diperkirakan menggunakan regresi Cox (fungsi coxph) Subdistribusi hazard tingkat kejadian sesaat dari jenis peristiwa tertentu pada subjek yang belum mengalami peristiwa jenis tersebut diperkirakan menggunakan regresi Fine-Grey (fungsi crr)
Katakanlah kita tertarik untuk melihat pengaruh usia dan jenis kelamin pada kematian akibat melanoma, dengan kematian akibat penyebab lain sebagai peristiwa bersaing.
Catatan:
crr membutuhkan spesifikasi kovariat sebagai matriks
Jika lebih dari satu peristiwa yang menarik, anda dapat meminta hasil untuk peristiwa yang berbeda dengan menggunakan opsi failcode, secara default hasil dikembalikan untuk failcode = 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
Dalam contoh sebelumnya, baik sex dan age diberi kode sebagai variabel numerik. Fungsi crr tidak dapat menangani variabel karakter secara alami, dan anda akan mendapatkan error, jadi jika variabel karakter ada, 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
hasil Keluaran dari crr saat ini tidak didukung oleh broom::tidy() atau gtsummary::tbl_regress(). Sebagai alternatif, coba mvcrrres (tidak fleksibel, tapi lebih baik daripada tidak sama sekali) Dari paket ezfun 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 bahaya spesifik penyebab terhadap risiko yang bersaing.
Hasil dapat diformat dengan broom::tidy() atau gtsummary::tbl_regression()
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 |
lalu kita jalankan kode dibawah ini ( saya tidak jalankan karena rlang saya tidak bisa di update ke versi 0.4.10 )
gtsummary::tbl_regression(chr_fit, exp = TRUE)