You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在同一张图中绘制多条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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:50:29