R语言生存分析:ggsurvplot报错及plot显示累积风险图问题求助
生存分析绘图问题排查与解决
项目背景
正在开展一项生存分析项目,使用R语言分析两个数据集,探究生存时间与血液生物标志物的关联,其中一个数据集用于模型开发,另一个用于验证。
遇到的问题
- 调用
ggsurvplot()绘制生存曲线时触发报错:Error in data.frame(..., check.names = FALSE) : arguments imply differing number of rows: 174, 0, 348 - 使用
plot()绘制survfit对象时,输出的是累积风险图而非预期的生存曲线
两个数据集均存在上述问题,以下是针对开发数据集编写的代码:
library(survival) library(survminer) library(corrplot) library(readxl) # development dataset (sheet 1 of 2 of the xlsx document) dati_D = read_excel("carvalho-prognostic-biomarkers-NSCLC.xlsx", sheet=2) # renaming some variables' names because of backspace in names colnames(dati_D)[colnames(dati_D) == "Lymph nodes"] = "LymphNodes" colnames(dati_D)[colnames(dati_D) == "RT Protocol"] = "RTProtocol" colnames(dati_D)[colnames(dati_D) == "Total dose (1st)"] = "TotalDose1st" colnames(dati_D)[colnames(dati_D) == "Total Dose (2nd)"] = "TotalDose2nd" colnames(dati_D)[colnames(dati_D) == "IL 6"] = "IL6" colnames(dati_D)[colnames(dati_D) == "IL 8"] = "IL8" colnames(dati_D)[colnames(dati_D) == "Cyfra 21-1"] = "Cyfra211" colnames(dati_D)[colnames(dati_D) == "WHO-PS"] = "WHOPS" colnames(dati_D)[colnames(dati_D) == "CA-9"] = "CA9" colnames(dati_D)[colnames(dati_D) == "FEV1s%"] = "FEV1s" # setting chr's as factors dati_D$Status = as.factor(dati_D$Status) dati_D$histology = as.factor(dati_D$histology) dati_D$stage = as.factor(dati_D$stage) dati_D$Gender = as.factor(dati_D$Gender) dati_D$RT_Protocol = as.factor(dati_D$RTProtocol) str(dati_D) # Survival curves c1 = survfit(Surv(Survival, Status) ~ Gender, data = dati_D) plot(c1) # it gives a cumulative hazard plot, why? ggsurvplot(c1, data = dati_D) # it gives the error mentioned above, why?
已尝试删除所有NA值、不将字符型变量转为因子,但问题仍未解决。数据集规模为182行21列,不清楚报错中的数字含义,需要协助排查解决。
问题排查与解决方案
问题1:plot()输出累积风险图而非生存曲线
survival包的plot.survfit()默认根据survfit对象的类型判断绘图逻辑,核心原因是事件变量Status的编码不符合生存分析标准:
- 生存分析要求
Surv()函数的事件变量为二分变量,其中0代表删失(存活),1代表事件发生(死亡)。若编码反向(比如1代表存活、0代表死亡),survfit会误判为累积风险计算。
解决步骤:
- 检查
Status变量取值:table(dati_D$Status) - 若编码反向,调整为标准格式:
# 假设原Status是1=存活,0=死亡,反转编码 dati_D$Status = as.numeric(dati_D$Status == 0) - 重新拟合并绘图,若需强制绘制生存曲线,可指定
fun="surv":c1 = survfit(Surv(Survival, Status) ~ Gender, data = dati_D) plot(c1, fun="surv")
问题2:ggsurvplot()报错行数不匹配
报错中的数字是不同数据对象的行数,说明survfit对象c1与输入数据集dati_D存在数据不匹配,主要由以下原因导致:
变量名拼写错误:
代码中存在一处明显错误:dati_D$RT_Protocol = as.factor(dati_D$RTProtocol)此处创建了新变量
RT_Protocol,但原变量名为RTProtocol,会导致数据集元数据异常,修正为:dati_D$RTProtocol = as.factor(dati_D$RTProtocol)survfit自动删去含NA的行,但ggsurvplot仍使用原始数据集:survfit()默认会自动删除含缺失值的观测(na.action=na.omit),导致c1中的观测数少于原始dati_D。解决方法是使用拟合后保留的数据集绘图:# 提取survfit中实际使用的数据集 dati_fit = c1$data # 重新拟合并绘图 c1 = survfit(Surv(Survival, Status) ~ Gender, data = dati_fit) ggsurvplot(c1, data = dati_fit)因子水平不一致:
检查Gender变量的因子水平,确保拟合前后无变化:str(dati_D$Gender) str(c1$strata)
验证步骤
- 先修正变量名错误并清理数据集:
# 修正RTProtocol的因子转换 dati_D$RTProtocol = as.factor(dati_D$RTProtocol) # 移除所有含NA的观测 dati_clean = na.omit(dati_D) - 确认
Status编码正确:table(dati_clean$Status) # 确保输出为0和1,且0代表删失、1代表事件 - 重新拟合并绘图:
c1 = survfit(Surv(Survival, Status) ~ Gender, data = dati_clean) plot(c1) # 验证生存曲线是否正常输出 ggsurvplot(c1, data = dati_clean) # 验证ggsurvplot是否正常运行
内容的提问来源于stack exchange,提问作者unbiased95
相关产品推荐
相关产品推荐

