如何在同一张图中绘制多条ROC曲线并标注最优阈值?
解决ggroc绘制多条ROC曲线并标注最优阈值的问题
由于ggroc没有直接支持批量标注最优阈值的参数,我们可以先预计算每条ROC曲线的最优阈值及对应坐标,再手动添加到ggplot图中。以下是完整实现步骤:
1. 预处理数据并创建ROC对象列表
首先将数据转换为pROC要求的正确类型,再生成每个预测变量的ROC对象:
library(ggplot2) library(pROC) # 转换数据类型:response转因子,predictor转数值 dataframe$response <- as.factor(dataframe$response) dataframe[, c("predictor1", "predictor2", "predictor3")] <- lapply( dataframe[, c("predictor1", "predictor2", "predictor3")], as.numeric ) # 创建命名的ROC对象列表 roc_list <- list( 预测变量1 = roc(dataframe$response, dataframe$predictor1), 预测变量2 = roc(dataframe$response, dataframe$predictor2), 预测变量3 = roc(dataframe$response, dataframe$predictor3) )
2. 提取最优阈值及对应坐标
使用coords()函数获取每条ROC曲线的最优阈值(默认基于Youden指数),并整理成标注用的数据框:
# 批量提取最优阈值及对应坐标 thresh_annot <- lapply(names(roc_list), function(name) { roc_obj <- roc_list[[name]] # 获取最优阈值对应的灵敏度、特异度 best_coords <- coords(roc_obj, x = "best", input = "threshold", transpose = FALSE) # ROC曲线x轴为「1-特异度」,需转换坐标 data.frame( group = name, x = 1 - best_coords$specificity, y = best_coords$sensitivity, threshold = round(best_coords$threshold, 2) ) }) thresh_annot <- do.call(rbind, thresh_annot)
3. 绘制带阈值标注的多条ROC曲线
用ggroc绘制基础曲线,再通过geom_point()和geom_text()添加阈值点和标注:
# 绘制基础ROC曲线 p <- ggroc(roc_list, aes = "color") + theme_minimal() + labs(x = "1 - 特异度", y = "灵敏度", color = "预测变量") + # 标记最优阈值点 geom_point(data = thresh_annot, aes(x = x, y = y, color = group), size = 3) + # 添加阈值文本标注(调整hjust/vjust避免重叠) geom_text( data = thresh_annot, aes(x = x, y = y, color = group, label = paste("阈值:", threshold)), hjust = -0.1, vjust = -0.1, size = 4 ) print(p)
百分比坐标轴版本(可选)
如果需要用百分比显示坐标轴,只需在创建ROC对象和提取坐标时同步设置percent=TRUE:
# 创建百分比模式的ROC对象 roc_list_percent <- list( 预测变量1 = roc(dataframe$response, dataframe$predictor1, percent = TRUE), 预测变量2 = roc(dataframe$response, dataframe$predictor2, percent = TRUE), 预测变量3 = roc(dataframe$response, dataframe$predictor3, percent = TRUE) ) # 提取百分比模式下的阈值坐标 thresh_annot_percent <- lapply(names(roc_list_percent), function(name) { roc_obj <- roc_list_percent[[name]] best_coords <- coords(roc_obj, x = "best", input = "threshold", transpose = FALSE) data.frame( group = name, x = 100 - best_coords$specificity, y = best_coords$sensitivity, threshold = round(best_coords$threshold, 2) ) }) thresh_annot_percent <- do.call(rbind, thresh_annot_percent) # 绘制百分比版本的ROC曲线 p_percent <- ggroc(roc_list_percent, aes = "color", percent = TRUE) + theme_minimal() + labs(x = "100 - 特异度(%)", y = "灵敏度(%)", color = "预测变量") + geom_point(data = thresh_annot_percent, aes(x = x, y = y, color = group), size = 3) + geom_text( data = thresh_annot_percent, aes(x = x, y = y, color = group, label = paste("阈值:", threshold)), hjust = -0.1, vjust = -0.1, size = 4 ) print(p_percent)
内容的提问来源于stack exchange,提问作者Abdulrazzaq Alheraky
相关产品推荐
相关产品推荐

