在外部验证集绘制 ROC、Calibration 校准曲线和 DCA 曲线的 R 源代码

文摘   科学   2023-10-30 22:34   上海  

在训练集建立 Logistic 回归模型,并将这个模型在训练集和验证集上分别绘制 ROC、校准曲线和 DCA 曲线,其原理和代码与在同一个数据集上建模和绘制曲线是不一样的,本教程特公布 R 源代码

近期我们发现有一些用户在做 Logistic nomogram 研究的时候,在训练集和验证集上分别建模和绘制曲线,而且结果已经发表,但这种做法是不对的。

因为现在卖的比较火的几本临床预测研究的书中,没有给出如何在验证集上做ROC、校准曲线和 DCA 曲线,只给了在同一个数据集上同时建模和绘制曲线,导致很多用户以为用同一套代码,把数据集名称改了,就可以达到目的,最终酿成大错。


正确的做法应该是,在训练集上建立 Logistic 模型和 nomogram, 用这个模型分别在训练集、内部验证集和外部验证集上做ROC、校准曲线和DCA曲线。下文就具体给出参考代码:


错误的做法:在训练集和验证集分别建立 Logistic 回归模型,分别做各种曲线   ×

正确的做法:在训练集建立 Logistic 回归模型,用同一个模型在训练集和验证集分别做各种曲线   √


数据集拆分的R代码示例:

# 加载所需的库library(caret)
# 假设我们有一个名为data的数据框data <- your_data
# 设置种子以确保结果的可重复性set.seed(123)
# 创建数据拆分:80%训练,20%内部验证trainIndex <- createDataPartition(data$your_response_variable, p = .8, list = FALSE, times = 1)
# 创建训练集和内部验证集train_data <- data[ trainIndex,]validation_data <- data[-trainIndex,]
# 假设我们有一个名为external_data的外部验证数据集external_data <- your_external_data


建立logistic 回归和 nomogram R代码示例:

# 加载所需的库library(rms)
# 设置模型公式# 假设我们的响应变量是response,并且我们有两个预测变量 predictor1 和 predictor2formula <- as.formula("response ~ predictor1 + predictor2")
# 首先,我们需要为我们的数据设置一个数据分布对象# 这会帮助rms包更好地理解我们的数据结构ddist <- datadist(train_data)options(datadist = "ddist")
# 现在我们可以在训练数据上拟合logistic回归模型logistic_model <- lrm(formula, data = train_data, x = TRUE, y = TRUE)
# 查看模型摘要以了解拟合情况summary(logistic_model)
# 生成 nomogramnom <- nomogram(logistic_model, fun = function(x) 1/(1 + exp(-x)), funlabel = "Predicted Probability")
# 绘制 nomogramplot(nom)

用训练集建立模型,并在其他集上做ROC R代码示例:


# 加载所需的库library(rms)library(pROC)

# 我们在训练集上构建 logistic 回归模型。假设我们想要使用变量 var1, var2, var3 来预测响应变量 response。formula <- as.formula("response ~ var1 + var2 + var3")logistic_model <- lrm(formula, data = train_data)
# 现在 logistic_model 是我们的训练模型,我们可以使用它来进行预测和分析。
# 使用训练集上的模型在训练集、内部验证集和外部验证集上进行预测train_predictions <- predict(logistic_model, train_data, type = "fitted")validation_predictions <- predict(logistic_model, validation_data, type = "fitted")external_predictions <- predict(logistic_model, external_data, type = "fitted") # 假设 external_data 是外部验证集
# 在训练集上绘制ROC曲线roc_train <- roc(train_data$response, train_predictions)auc_train <- auc(roc_train)plot.roc(roc_train, main = paste("Training Set ROC - AUC =", round(auc_train, 2)))
# 在内部验证集上绘制ROC曲线roc_validation <- roc(validation_data$response, validation_predictions)auc_validation <- auc(roc_validation)plot.roc(roc_validation, main = paste("Validation Set ROC - AUC =", round(auc_validation, 2)))
# 在外部验证集上绘制ROC曲线roc_external <- roc(external_data$response, external_predictions)auc_external <- auc(roc_external)plot.roc(roc_external, main = paste("External Set ROC - AUC =", round(auc_external, 2)))


用训练集建立模型,并在其他集上做calibration曲线 R代码示例:

# 加载必要的库library(riskRegression)
# 使用glm()函数在训练集上建立logistic回归模型formula <- as.formula(glue("response ~ predictor1 + predictor2 + ..."))logistic_model <- glm(formula, family = binomial(), data = train_data)
# 使用 riskRegression 包的 Score 函数来获取calibration数据# 在训练集上cal_train <- riskRegression::Score( object = list(fit = logistic_model), formula = as.formula("response ~ 1"), data = train_data)
# 在内部验证集上cal_validation <- riskRegression::Score( object = list(fit = logistic_model), formula = as.formula("response ~ 1"), data = validation_data)
# 在外部验证集上cal_external <- riskRegression::Score( object = list(fit = logistic_model), formula = as.formula("response ~ 1"), data = external_data)
# 绘制calibration曲线# 在训练集上riskRegression::plotCalibration(x = cal_train, xlab = "Predicted Risk", ylab = "Observed Risk", col = "black", brier.in.legend = TRUE, auc.in.legend = TRUE)
# 在内部验证集上riskRegression::plotCalibration(x = cal_validation, xlab = "Predicted Risk", ylab = "Observed Risk", col = "black", brier.in.legend = TRUE, auc.in.legend = TRUE)
# 在外部验证集上riskRegression::plotCalibration(x = cal_external, xlab = "Predicted Risk", ylab = "Observed Risk", col = "black", brier.in.legend = TRUE, auc.in.legend = TRUE)

用训练集建立模型,并在其他集上做DCA 曲线 R代码示例:

# 加载必要的库library(rmda)
# 使用glm()函数在训练集上建立logistic回归模型formula <- as.formula(glue("response ~ predictor1 + predictor2 + ..."))logistic_model <- glm(formula, family = binomial(), data = train_data)
# 获取训练集、内部验证集和外部验证集的预测值train_data$pred <- predict(logistic_model, train_data, type = "response")validation_data$pred <- predict(logistic_model, validation_data, type = "response")external_data$pred <- predict(logistic_model, external_data, type = "response")
# 在训练集上生成DCAdca_train <- rmda::decision_curve(formula = as.formula(glue("response ~ pred")), data = train_data, family = binomial(), thresholds = seq(0, 1, by = 0.01))
# 在内部验证集上生成DCAdca_validation <- rmda::decision_curve(formula = as.formula(glue("response ~ pred")), data = validation_data, family = binomial(), thresholds = seq(0, 1, by = 0.01))
# 在外部验证集上生成DCAdca_external <- rmda::decision_curve(formula = as.formula(glue("response ~ pred")), data = external_data, family = binomial(), thresholds = seq(0, 1, by = 0.01))
# 绘制DCA曲线# 在训练集上rmda::plot_decision_curve(dca_train, col = "#E64B35B2", standardize = FALSE)
# 在内部验证集上rmda::plot_decision_curve(dca_validation, col = "#E64B35B2", standardize = FALSE)
# 在外部验证集上rmda::plot_decision_curve(dca_external, col = "#E64B35B2", standardize = FALSE)



如果不会编程的朋友,可以登录 www.mstata.com ,点击网站左上角的MSTATA医学统计机器人,选以研究类型分类-预测研究回归 - Logistic - nomogram 预测研究(一键生成 SCI 论文)。上面已经把整个流程自动打包,只需要鼠标点一点就能完成所有过程,直到生成一篇完整的 3000 字左右的 SCI 论文。



真实世界数据
介绍真实世界数据,真实世界研究和真实世界证据
 最新文章