1 列线图

列线图(Nomogram)是一种可视化工具,用于展示多个预测变量对某个结果变量(如疾病发生、存活率等)的影响。通过列线图,可以直观地评估某个特定数据点的预测结果,主要用于展示回归模型中预测变量对结果的影响。以下是如何读取和解释列线图的步骤:

列线图的结构 预测变量: 列线图上通常会有几条垂直的线段或条形图,每条线代表一个预测变量。这些变量通常被标记在图表的顶部。

分数刻度: 每个预测变量的线段上都有刻度,表示不同值对应的分数。例如,某个变量的值在图中可能会转化为0到100的分数区间。

分数总计: 列线图的一侧通常有一个分数总计的区域。这一部分展示了所有预测变量的分数加和后的总分。

预测结果: 分数总计区域的下方通常会有一个结果预测区域,显示基于总分的预测结果。例如,结果可能是某个事件发生的概率(如疾病的发生率)或某个时间点的生存概率。

1.1 Cox模型列线图

Code
library(survival)

library(rms)




# 创建一个示例数据框
set.seed(123)  # 为了结果可重复
n <- 100  # 样本大小
data <- data.frame(
    time = rexp(n, 0.1),  # 生存时间
    status = sample(0:1, n, replace = TRUE),  # 生存状态(0=删失,1=事件)
    age = sample(40:80, n, replace = TRUE),  # 年龄
    sex = sample(c("male", "female"), n, replace = TRUE)  # 性别
)
# 创建一个rms包的数据对象
dd <- datadist(data)
options(datadist = "dd")
# 拟合Cox模型
cox_model <- coxph(Surv(time, status) ~ age + sex, data = data)



# 拟合Cox模型(rms包)
cox_model_rms <- cph(Surv(time, status) ~ age + sex, data = data)

# 绘制列线图
nom <- nomogram(cox_model_rms, fun=list(function(x) x), lp=FALSE)
plot(nom)

识别变量: 确定图中所有预测变量及其对应的分数刻度。每个预测变量的线段应有不同的刻度,表示不同的数值区间。

获取分数: 对于每个预测变量,找到对应值的分数。例如,如果年龄为50岁,查看“年龄”线段上50岁的位置,对应的分数可能是30分。

计算总分: 将所有预测变量的分数加起来。例如,如果年龄得30分,性别得20分,BMI得15分,则总分为65分。

读取预测结果: 查找总分对应的结果预测区域。例如,如果总分为65分,则在结果预测区域中找到对应的概率或预期结果。如果总分65对应的概率是70%,这意味着根据模型预测,事件发生的概率是70%。

1.2 逻辑回归列线图

Code
# 创建示例数据

df <- read_csv("data/诺莫图.csv") %>% 
    mutate(across(everything(), as.factor))
#> Rows: 277 Columns: 4
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> dbl (4): 年龄是否大于5岁, 抗生素经验治疗与否, 是否植入PICC管, 转归
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

str(df)
#> tibble [277 × 4] (S3: tbl_df/tbl/data.frame)
#>  $ 年龄是否大于5岁   : Factor w/ 2 levels "0","1": 1 2 1 1 1 2 1 1 1 1 ...
#>  $ 抗生素经验治疗与否: Factor w/ 2 levels "0","1": 2 2 2 2 2 2 1 2 2 2 ...
#>  $ 是否植入PICC管    : Factor w/ 2 levels "0","1": 1 1 1 2 2 1 1 2 1 1 ...
#>  $ 转归              : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...

# 创建数据分布对象
dd <- datadist(df)
options(datadist = "dd")

# 拟合多元逻辑回归模型
logit_model <- lrm(转归 ~ 年龄是否大于5岁 +抗生素经验治疗与否 + 是否植入PICC管,
                   data = df)

# 创建列线图
nom <- nomogram(logit_model, fun=plogis,lp = F,
                funlabel = "预后良好的概率")
#> Warning in formula.character(object, env = baseenv()): Using formula(x) is deprecated when x is a character vector of length > 1.
#>   Consider formula(paste(x, collapse = " ")) instead.
plot(nom, 
     col.grid = c(0.8, 0.95),  # 网格颜色
     xfrac = 0.45,             # x 轴缩放比例
     cex.var = 1.2,            # 变量标签大小
     cex.axis = 1.2,           # 轴标签大小
     cex.lab = 1.5,            # 标签大小
     col.lab = "black",
     points.label='得分(分)', total.points.label='总得分(分)')        # 标签颜色

1.3 风险评分模型

Code
library(rms)
library(Hmisc)

# 示例数据
set.seed(123)
n <- 200
data <- data.frame(
  outcome = sample(c(0, 1), n, replace = TRUE),
  age = rnorm(n, 50, 10),
  gender = factor(sample(c("male", "female"), n, replace = TRUE)),
  bmi = rnorm(n, 25, 5)
)

# 创建数据分布对象
dd <- datadist(data)
options(datadist = "dd")

# 拟合逻辑回归模型
logit_model <- lrm(outcome ~ age + gender + bmi, data = data)

# 计算风险评分
data$score <- predict(logit_model, type = "lp")
# 创建列线图
nom <- nomogram(logit_model, fun=list(function(x) x), lp=FALSE)
plot(nom)

Code

# 显示模型系数
summary(logit_model)
#>              Effects              Response : outcome 
#> 
#>  Factor               Low    High   Diff.   Effect    S.E.    Lower 0.95
#>  age                  43.814 56.105 12.2900 -0.196870 0.18429 -0.55807  
#>   Odds Ratio          43.814 56.105 12.2900  0.821290      NA  0.57231  
#>  bmi                  22.212 28.405  6.1925  0.212520 0.18552 -0.15110  
#>   Odds Ratio          22.212 28.405  6.1925  1.236800      NA  0.85976  
#>  gender - male:female  1.000  2.000      NA  0.032107 0.28540 -0.52728  
#>   Odds Ratio           1.000  2.000      NA  1.032600      NA  0.59021  
#>  Upper 0.95
#>  0.16432   
#>  1.17860   
#>  0.57613   
#>  1.77910   
#>  0.59149   
#>  1.80670
Back to top