# 安装包
if (!requireNamespace("data.table", quietly = TRUE)) {
install.packages("data.table")
}
if (!requireNamespace("jsonlite", quietly = TRUE)) {
install.packages("jsonlite")
}
if (!requireNamespace("rms", quietly = TRUE)) {
install.packages("rms")
}
if (!requireNamespace("survival", quietly = TRUE)) {
install.packages("survival")
}
if (!requireNamespace("ggplot2", quietly = TRUE)) {
install.packages("ggplot2")
}
if (!requireNamespace("stringr", quietly = TRUE)) {
install.packages("stringr")
}
# 加载包
library(data.table)
library(jsonlite)
library(rms)
library(survival)
library(ggplot2)
library(stringr)限制性立方样条 COX 模型
注记
Hiplot 网站
本页面为 Hiplot RCS-COX 插件的源码版本教程,您也可以使用 Hiplot 网站实现无代码绘图,更多信息请查看以下链接:
非线性回归分析。
环境配置
系统: Cross-platform (Linux/MacOS/Windows)
编程语言: R
依赖包:
data.table;jsonlite;rms;survival;ggplot2;stringr
sessioninfo::session_info("attached")─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.5.2 (2025-10-31)
os Ubuntu 24.04.3 LTS
system x86_64, linux-gnu
ui X11
language (EN)
collate C.UTF-8
ctype C.UTF-8
tz UTC
date 2026-01-18
pandoc 3.1.3 @ /usr/bin/ (via rmarkdown)
quarto 1.8.27 @ /usr/local/bin/quarto
─ Packages ───────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
data.table * 1.18.0 2025-12-24 [1] RSPM
ggplot2 * 4.0.1 2025-11-14 [1] RSPM
Hmisc * 5.2-5 2026-01-09 [1] RSPM
jsonlite * 2.0.0 2025-03-27 [1] RSPM
rms * 8.1-0 2025-10-14 [1] RSPM
stringr * 1.6.0 2025-11-04 [1] RSPM
survival * 3.8-3 2024-12-17 [3] CRAN (R 4.5.2)
[1] /home/runner/work/_temp/Library
[2] /opt/R/4.5.2/lib/R/site-library
[3] /opt/R/4.5.2/lib/R/library
* ── Packages attached to the search path.
──────────────────────────────────────────────────────────────────────────────
数据准备
# 加载数据
data <- data.table::fread(jsonlite::read_json("https://hiplot.cn/ui/basic/rcs-cox/data.json")$exampleData$textarea[[1]])
data <- as.data.frame(data)
# 整理数据格式
data <- na.omit(data)
ex <- set::not(colnames(data), c("main", "time", "event"))
ex <- str_c(ex, collapse = "+")
dd <<- datadist(data)
options(datadist = "dd")
for (i in 3:5) {
fit <- coxph(as.formula(paste0("Surv(time, event) ~ rcs(main, nk = i, inclx = T)+", ex, collapse = "+")), data = data, x = TRUE)
tmp <- extractAIC(fit)
if (i == 3) {
AIC <- tmp[2]
nk <<- 3
}
if (tmp[2] < AIC) {
AIC <- tmp[2]
nk <<- i
}
}
fit <- cph(as.formula(paste0("Surv(time, event) ~ rcs(main, nk = nk, inclx = T)+", ex, collapse = "+")), data = data, x = TRUE)
dd$limits$main[2] <- median(data$main)
fit <- update(fit)
orr <- Predict(fit, main, fun = exp, ref.zero = TRUE)
# 查看数据
head(data) main x1 x2 time event
1 25.54051 1 1 2178 0
2 24.02398 1 2 2172 0
3 22.14290 1 3 2190 0
4 26.63187 1 4 297 1
5 24.41255 1 5 2131 0
6 23.24236 1 6 1 1
可视化
# 限制性立方样条 COX 模型
p <- ggplot() +
geom_line(data = orr, aes(main, yhat), linetype = "solid", size = 1, alpha = 1,
colour = "#FF0000") +
geom_ribbon(data = orr, aes(main, ymin = lower, ymax = upper), alpha = 0.6,
fill = "#FFC0CB") +
geom_hline(yintercept = 1, linetype = 2, size = 0.5) +
geom_vline(xintercept = dd$limits$main[2], linetype = 2, size = 0.5) +
labs(x = " ", y = "Hazard Ratio(95%CI)") +
theme_bw() +
theme(text = element_text(family = "Arial"),
plot.title = element_text(size = 12,hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
axis.text.x = element_text(angle = 0, hjust = 0.5,vjust = 1),
legend.position = "right",
legend.direction = "vertical",
legend.title = element_text(size = 10),
legend.text = element_text(size = 10))
p
