ÔÚÁÙ´²Ò½Ñ§Êµ¼ùÖУ¬Éú´æ·ÖÎöÊÇÒ»ÖÖÖØÒªµÄÑо¿·½·¨¡£Éú´æ·ÖÎöÊÇÑо¿Éú´æÊ±¼äµÄ·Ö²¼¹æÂÉ£¬ÒÔ¼°Éú´æÊ±¼äºÍÏà¹ØÒòËØÖ®¼ä¹ØÏµµÄÒ»ÖÖͳ¼Æ·ÖÎö·½·¨¡£ËüÖ÷ÒªµÄÄ¿µÄÊǶÔÉú´æÂʺÍʱ¼ä½øÐн¨Ä££¬¼ÆË㻼ÕßÔÚÌØ¶¨Ê±¼ä¶ÎÄÚÉú´æµÄ¸ÅÂÊ£¬Ö÷ÒªÓÃÓÚÆÀ¹ÀÖÎÁƵÄЧ¹ûºÍ¼²²¡µÄΣÏճ̶ȡ£
Éú´æ·ÖÎöµÄ·½·¨Ò»°ã¿ÉÒÔ·ÖΪÈýÀࣺ
²ÎÊý·¨£ºÖªµÀÉú´æÊ±¼äµÄ·Ö²¼Ä£ÐÍ£¬È»ºó¸ù¾ÝÊý¾ÝÀ´¹À¼ÆÄ£ÐͲÎÊý£¬×îºóÒÔ·Ö²¼Ä£ÐÍÀ´¼ÆËãÉú´æÂÊ ¡£
·Ç²ÎÊý·¨£º²»ÐèÒªÉú´æÊ±¼ä·Ö²¼£¬¸ù¾ÝÑù±¾Í³¼ÆÁ¿À´¹À¼ÆÉú´æÂÊ£¬³£¼û·½·¨Kaplan-Meier·¨£¨³Ë»ý¼«ÏÞ·¨£©¡¢Log-rank¼ìÑéµÈ
°ë²ÎÊý·¨£ºÒ²²»ÐèÒªÉú´æÊ±¼äµÄ·Ö²¼£¬µ«×îÖÕÊÇͨ¹ýÄ£ÐÍÀ´ÆÀ¹ÀÓ°ÏìÉú´æÂʵÄÒòËØ£¬×îΪ³£¼ûµÄÊÇCox»Ø¹éÄ£ÐÍ ¡£
Éú´æÇúÏߣ¨survival curve£©ÔòÊǽ«Ã¿¸öʱ¼äµãµÄÉú´æÂÊÁ¬½ÓÔÚÒ»ÆðµÄÇúÏߣ¬Ò»°ãËæ·Ãʱ¼äΪXÖᣬÉú´æÂÊΪYÖ᣻ÇúÏ߯½»¬Ôò˵Ã÷¸ßÉú´æÂÊ£¬·´Ö®ÔòµÍÉú´æÂÊ£»ÖÐλÉú´æÂÊ£¨median survival time£©Ô½³¤£¬Ôò˵Ã÷Ô¤ºó½ÏºÃ¡£±¾ÎÄÖ÷Òª½éÉÜÉú´æÇúÏߵĻæÖÆ¡£
°²×°Óë¼ÓÔØ
install.packages("survminer")
library("survminer")ggsurvplot»æÖÆÉú´æÇúÏß
#µ÷ÓÃsurvival°ü
require("survival")
#survival°ü×Ô´ø·Î°©Êý¾Ý¼¯£ºlung£¬²é¿´Êý¾ÝÑùʽ
head(lung)
> head(lung)
inst time status age sex ph.ecog ph.karno pat.karno meal.cal wt.loss
1 3 306 2 74 1 1 90 100 1175 NA
2 3 455 2 68 1 0 90 90 1225 15
3 3 1010 1 56 1 0 90 90 NA 15
4 5 210 2 57 1 1 90 60 1150 11
5 1 883 2 60 1 0 100 90 NA 0
6 12 1022 1 74 1 1 50 80 513 0»æÖÆ»ù´¡°æµ¥Ò»·Ö×éµÄÉú´æÇúÏß
#ͨ¹ýsurvival°üµÄSurvº¯Êý¶Ôʱ¼ä¼°Éú´æ×´Ì¬½øÐÐÄâºÏ(¼ìÑé: Kaplan-Meier·¨) fit1 <- survfit(Surv(time, status) ~ 1, data = lung) #»æÖÆ»ù´¡°æÉú´æÇúÏß ggsurvplot(fit, palette = "#2E9FDF") #×Ô¶¨ÒåÐÞ¸ÄÑÕÉ«

»æÖÆÁ½×éµÄÉú´æÇúÏß
#ÒÔÐÔ±ðÌØÕ÷½øÐзÖ×éΪÀý #»æÖÆ»ù´¡Í¼ÐÎ fit <- survfit(Surv(time, status) ~ sex, data = lung) ggsurvplot(fit, data = lung)

#¸ü¸ÄɾʧµãÐÎ×´¼°´óС£¬Ä¬ÈÏΪ"+", ¿ÉÑ¡"|" ggsurvplot(fit, data = lung, censor.shape="|", censor.size = 4)

# ʹÓÃÆ¡¾Æµ÷É«°å¡°Dark2¡± ggsurvplot(fit, linetype = "strata", conf.int = TRUE, pval = TRUE, palette = "Dark2")

# ʹÓûÒÉ«µ÷É«°å ggsurvplot(fit, linetype = "strata", conf.int = TRUE, pval = TRUE, palette = "grey")

#»¹Ö§³ÖÀۼƷçÏÕÇúÏß»æÖÆ ggsurvplot(fit, data = lung, conf.int = TRUE, # ÊÇ·ñÐèÒªÔö¼ÓÖÃÐÅÇø¼ä fun = "cumhaz") # cumhazº¯Êý»æÖÆÀۼƷçÏÕÇúÏß

# Ö¸¶¨Êý¾Ý£¬Ìí¼Ó×Ü»¼ÕßÉú´æÇúÏß ggsurvplot(fit, # ·Ö×éÄâºÏ¶ÔÏó data = lung, # ʹÓõıäÁ¿Êý¾Ý¼¯À´Ô´ conf.int = TRUE, # ÊÇ·ñÏÔʾÏÔʾÖÃÐÅÇø¼ä pval = TRUE, # ͨ¹ý pval Ìí¼ÓPÖµ surv.median.line = "hv", # surv.median.lineÌí¼ÓÖÐλÉú´æÊ±¼äÏß add.all = TRUE) # add.all Ìí¼Ó×Ü»¼ÕßÉú´æÇúÏß

# ͨ¹ýÐ޸ĺ¯Êý½Ó¿Ú£¬Öƶ¨¸öÐÔ»¯µÄÉú´æÇúÏß
ggsurvplot(
fit,
data = lung,
size = 1, # ÏßÌõ´Öϸ
palette =
c("#E7B800", "#2E9FDF"),# ÉèÖ÷Ö×éÑÕÉ«
conf.int = TRUE, # conf.int º¯ÊýÌí¼ÓÖÃÐÅÇø¼ä
pval = TRUE, # pÖµº¯ÊýÌí¼ÓÏÔÖøÐÔ
risk.table = TRUE, # Ìí¼Ó·çÏÕ±í¸ö»æÖÆ
risk.table.col = "strata",# ·ÖÏß±íÑÕÉ«
legend.labs =
c("Male", "Female"), # Ìí¼Ó¶ÔӦͼÀý±êÇ©
risk.table.height = 0.25, # Éú´æÇúÏßͼÏÂËùÓÐÉú´æ±íµÄ¸ß¶È£¬ÊýÖµ0-1Ö®¼ä
ggtheme = theme_bw() # ÊÇ·ñÌí¼ÓͼÖ÷Ìâ
)
# Ð޸IJÎÊý£¬¸ü¼Ó¸öÐÔ»¯µÄÉú´æÇúÏßͼ»æÖÆ ggsurvplot( fit, data = lung, risk.table = TRUE, pval = TRUE, conf.int = TRUE, xlim = c(0,500), # xlim, ylim º¯ÊýÖ¸¶¨xÖáºÍyÖáµÄ·¶Î§ xlab = "Time in days", # xlab, ylab ÕâÁ½¸öº¯Êý·Ö±ðÖ¸xÖáºÍyÖá±êÇ© break.time.by = 100, # Éè¶¨×ø±êÖá¿Ì¶È¼ä¾à´óС£¬°´ÐèÉèÖà ggtheme = theme_light(), risk.table.y.text.col = T, # ·ÖÏß±íyÖáÎÄ×Ö×ÖÌåÑÕÉ«£¬¿ÉÐÞ¸Ä risk.table.y.text = FALSE # ·çÏÕ±íyÖáչʾÌõÐÎͼÀý )

# Uber¶¨ÖÆÉú´æÇúÏß
ggsurv <- ggsurvplot(
fit,
data = lung,
risk.table = TRUE,
pval = TRUE,
conf.int = TRUE,
palette = c("#E7B800", "#2E9FDF"),
xlim = c(0,500),
xlab = "Time in days",
break.time.by = 100,
ggtheme = theme_light(),
risk.table.y.text.col = T,
risk.table.height = 0.25,
risk.table.y.text = FALSE,
ncensor.plot = TRUE,
ncensor.plot.height = 0.25,
conf.int.style = "step",
surv.median.line = "hv",
legend.labs =
c("Male", "Female")
)
ggsurv
# ÒýÈëcustomize_labels º¯Êý½øÐиü¸ß¼¶µÄ¶¨ÖÆ£¬ÕâÖÖº¯Êý¿É×÷Ϊsource¶ÔÏ󣬼ÓÔÚÖ®ºó¿ÉÒÔÖ±½Ó»æÖÆÏàÓ¦µÄÉú´æÇúÏß
customize_labels <- function (p, font.title = NULL,
font.subtitle = NULL, font.caption = NULL,
font.x = NULL, font.y = NULL, font.xtickslab = NULL, font.ytickslab = NULL)
{
original.p <- p
if(is.ggplot(original.p)) list.plots <- list(original.p)
else if(is.list(original.p)) list.plots <- original.p
else stop("Can't handle an object of class ", class (original.p))
.set_font <- function(font){
font <- ggpubr:::.parse_font(font)
ggtext::element_markdown (size = font$size, face = font$face, colour = font$color)
}
for(i in 1:length(list.plots)){
p <- list.plots[[i]]
if(is.ggplot(p)){
if (!is.null(font.title)) p <- p + theme(plot.title = .set_font(font.title))
if (!is.null(font.subtitle)) p <- p + theme(plot.subtitle = .set_font(font.subtitle))
if (!is.null(font.caption)) p <- p + theme(plot.caption = .set_font(font.caption))
if (!is.null(font.x)) p <- p + theme(axis.title.x = .set_font(font.x))
if (!is.null(font.y)) p <- p + theme(axis.title.y = .set_font(font.y))
if (!is.null(font.xtickslab)) p <- p + theme(axis.text.x = .set_font(font.xtickslab))
if (!is.null(font.ytickslab)) p <- p + theme(axis.text.y = .set_font(font.ytickslab))
list.plots[[i]] <- p
}
}
if(is.ggplot(original.p)) list.plots[[1]]
else list.plots
}
#Óû§×Ô¶¨ÒåÉú´æÇúÏß
ggsurv$plot <- ggsurv$plot + labs(
title = "Survival curves", #Ö÷±êÌ⣬¿É¸Äд
subtitle = "Based on Kaplan-Meier estimates", #Ìí¼Ó¸±±êÌâ
caption = "created with survminer" # ÊÇ·ñÐèҪ˵Ã÷
)
ggsurv$plot
# µ¥¶À»æÖÆ·çÏÕ±í¸ñ ggsurv$table <- ggsurv$table + labs( title = "Note the risk set sizes", subtitle = "and remember about censoring.", caption = "source code: website.com" ) ggsurv$table

# »æÖÆÉ¾Ê§Í¼±êÇ© ggsurv$ncensor.plot <- ggsurv$ncensor.plot + labs( title = "Number of censorings", subtitle = "over the time.", caption = "source code: website.com" ) ggsurv$ncensor.plot

# ×Ô¶¨ÒåÐÞ¸ü¸Ä×ÖÌå´óС¡¢ÀàÐͺÍÑÕÉ« ggsurv <- customize_labels( ggsurv, font.title = c(16, "bold", "darkblue"), font.subtitle = c(15, "bold.italic", "purple"), font.caption = c(14, "plain", "orange"), font.x = c(14, "bold.italic", "red"), font.y = c(14, "bold.italic", "darkred"), font.xtickslab = c(12, "plain", "darkgreen") ) ggsurv

»æÖƶà×éÉú´æÇúÏßͼ
# ¶à×éÉú´æÇúÏßÒ²¿ÉÒÔµ÷ÓÃÏàÓ¦µÄº¯ÊýÀ´»æÖÆ # ÔÙÀ´¿´¿´ÄÚÖÃÊý¾Ý¼¯colon head(colon) > head(colon) id study rx sex age obstruct perfor adhere 1 1 1 Lev+5FU 1 43 0 0 0 2 1 1 Lev+5FU 1 43 0 0 0 3 2 1 Lev+5FU 1 63 0 0 0 4 2 1 Lev+5FU 1 63 0 0 0 5 3 1 Obs 0 71 0 0 1 6 3 1 Obs 0 71 0 0 1 nodes status differ extent surg node4 time etype 1 5 1 2 3 0 1 1521 2 2 5 1 2 3 0 1 968 1 3 1 0 2 3 0 0 3087 2 4 1 0 2 3 0 0 3087 1 5 7 1 2 2 0 1 963 2 6 7 1 2 2 0 1 542 1 #rx·Ö×é fit2 <- survfit( Surv(time, status) ~ rx + adhere, data = colon ) ggsurvplot(fit2, pval = TRUE, break.time.by = 800, risk.table = TRUE, risk.table.height = 0.5 )

ʵÑéÍâ°ü ÏëÁ˽â¸ü¶àÇë¹Ø×¢£º



