如何将pROC生成的S3:roc对象转换为ggplot2兼容格式并组装?
解决方案
1. 用pROC内置的ggroc()生成ggplot对象(直接兼容patchwork)
pROC自带ggroc()函数,可直接将roc对象转换为ggplot对象,完美解决wrap_plots()仅支持ggplot/grob的报错问题,无需折腾fortify转换。示例代码:
library(pROC) library(ggplot2) library(patchwork) # 生成示例数据 set.seed(123) data_a <- data.frame(response = sample(c(0,1), 100, replace=T), predictor = rnorm(100)) data_b <- data.frame(response = sample(c(0,1), 100, replace=T), predictor = rnorm(100)) # 生成roc对象 roc_a <- roc(response ~ predictor, data = data_a) roc_b <- roc(response ~ predictor, data = data_b) # 转换为ggplot对象 plot_a <- ggroc(roc_a, color = "red") + ggtitle("ROC Curve A") plot_b <- ggroc(roc_b, color = "blue") + ggtitle("ROC Curve B") # patchwork拼接 wrap_plots(plot_a, plot_b, ncol=2)
2. 自动标注Youden指数、置信区间及AUC置信区间
基于ggroc生成的ggplot,结合pROC内置函数提取统计量,用annotate()或geom_text()添加标注:
# 提取AUC及95%置信区间 auc_ci_a <- ci.roc(roc_a, of="auc") auc_text_a <- sprintf("AUC: %.2f (95%% CI: %.2f-%.2f)", auc_ci_a[2], auc_ci_a[1], auc_ci_a[3]) # 提取Youden指数对应点及置信区间 youden_coords_a <- coords(roc_a, "best", ret=c("threshold", "sensitivity", "specificity"), transpose=FALSE) youden_ci_a <- ci.coords(roc_a, x="best", ret=c("sensitivity", "specificity")) youden_text_a <- sprintf("Youden Point\nThreshold: %.2f\nSens: %.2f (%.2f-%.2f)\nSpec: %.2f (%.2f-%.2f)", youden_coords_a$threshold, youden_coords_a$sensitivity, youden_ci_a$sensitivity[1], youden_ci_a$sensitivity[3], youden_coords_a$specificity, youden_ci_a$specificity[1], youden_ci_a$specificity[3]) # 把标注加到图上 plot_a_annotated <- plot_a + # 标记Youden点 geom_point(aes(x=1-youden_coords_a$specificity, y=youden_coords_a$sensitivity), color="red", size=2) + # 添加文本标注 annotate("text", x=0.6, y=0.2, label=auc_text_a, hjust=0) + annotate("text", x=0.6, y=0.05, label=youden_text_a, hjust=0, size=3.5) + # 调整主题避免文本问题 theme_minimal() + theme(text = element_text(size=11), plot.title = element_text(size=12, face="bold")) # 同理处理plot_b后拼接 wrap_plots(plot_a_annotated, plot_b_annotated, ncol=2)
3. 解决文本大小与布局问题
放弃基础绘图的par(cex),改用ggplot的主题系统精准控制:
- 全局调整文本大小:
theme(text = element_text(size=12)) - 单独控制标题、坐标轴、图例:
plot.title = element_text(size=14),axis.text = element_text(size=10) - 标注文本通过
size参数和x/y坐标调整位置,避免重叠;批量处理时可封装函数自动计算空白区域作为标注位置
封装函数实现批量处理
如果需要批量生成带标注的ROC图并拼接,可封装成复用函数:
create_annotated_roc <- function(roc_obj, plot_title, color="black") { # 提取AUC及CI auc_ci <- ci.roc(roc_obj, of="auc") auc_text <- sprintf("AUC: %.2f (95%% CI: %.2f-%.2f)", auc_ci[2], auc_ci[1], auc_ci[3]) # 提取Youden点及CI youden_coords <- coords(roc_obj, "best", ret=c("threshold", "sensitivity", "specificity"), transpose=FALSE) youden_ci <- ci.coords(roc_obj, x="best", ret=c("sensitivity", "specificity")) youden_text <- sprintf("Youden Point\nThreshold: %.2f\nSens: %.2f (%.2f-%.2f)\nSpec: %.2f (%.2f-%.2f)", youden_coords$threshold, youden_coords$sensitivity, youden_ci$sensitivity[1], youden_ci$sensitivity[3], youden_coords$specificity, youden_ci$specificity[1], youden_ci$specificity[3]) # 生成带标注的ggplot p <- ggroc(roc_obj, color=color) + ggtitle(plot_title) + geom_point(aes(x=1-youden_coords$specificity, y=youden_coords$sensitivity), color=color, size=2) + annotate("text", x=0.6, y=0.2, label=auc_text, hjust=0) + annotate("text", x=0.6, y=0.05, label=youden_text, hjust=0, size=3.5) + theme_minimal() + theme(text = element_text(size=11), plot.title = element_text(size=12, face="bold")) return(p) } # 批量生成并拼接 plots <- list( create_annotated_roc(roc_a, "ROC Curve A", "red"), create_annotated_roc(roc_b, "ROC Curve B", "blue") ) wrap_plots(plots, ncol=2)
内容的提问来源于stack exchange,提问作者Baytars
相关产品推荐
相关产品推荐

