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

rms::lrm中使用offset报‘sformula not found’错误的技术问询

问题:rms::lrm使用offset时出现sformula not found错误

尝试将已开发完成的模型放入lrm框架中,使用validate函数进行bootstrap验证,但引入offset项(已知系数)时出现以下错误:

Error in lrm(Death ~ offset(2 * Age), data = patient_data) : 
  object 'sformula' not found

尽管帮助文档说明offset在rms::lrm中可用,但仍出现该错误。以下是可复现代码:

library(rms) 

patient_data <- data.frame(
  PatientID = 1:1000,
  Death = sample(c(0, 1), size = 1000, replace = TRUE),
  Age = round(runif(1000, min = 20, max = 90), 1)
  )

lrm(Death~Age, data = patient_data) #运行正常
glm(Death ~ Age, family = "binomial", data = patient_data) #运行正常
glm(Death ~ offset(2*Age), family = "binomial", data = patient_data) #运行正常

lrm(Death ~ offset(2*Age),data = patient_data) #报错

补充内容

目前暂无该bug的官方解决方案,提供一个替代方案,请求验证代码正确性:

# Define the function which will be applied to each bootstraped sample. 
# Note, boot() will output the original data and a list of indices to construct 
# bootstrapped sample

fBootMetrics <- function(tblOrgData, intIndex) {
  
  # Create a bootstrap sample using the provided indices
  tblBootData <- tblOrgData[intIndex, ]
  
  # Fit the logistic regression model on the bootstrap sample
  # The model uses coefficients from the above LASSO penalised model
  mdlDeathBoot <- glm(
    Death ~ 0 + offset(2 * Age),
    family = "binomial",
    data = tblBootData
  )
  
  # Obtain predicted probabilities on the bootstrap sample (apparent) and test
  pred_boot <- predict(mdlDeathBoot, type = "response", newdata = tblBootData)
  pred_org  <- predict(mdlDeathBoot, type = "response", newdata = tblOrgData)
  # Convert Death to numeric and subtract 1 as the factor levels are "1" and "2"
  y_boot <- as.numeric(tblBootData$Death) - 1
  y_org  <- as.numeric(tblOrgData$Death) - 1
  
    return(rms::val.prob(pred_boot, y_boot, pl = FALSE)[c("Dxy", "Intercept", "Slope")] - rms::val.prob(pred_org, y_org, pl = FALSE)[c("Dxy", "Intercept", "Slope")])
}


boot(data = patient_data,
     statistic = fBootMetrics,
     R = 50)$t -> tblMdlPerformance

colnames(tblMdlPerformance) <- c("Dxy", "Intercept", "Slope")
解答

错误原因

这个错误是rms::lrm的内部逻辑bug:当模型仅包含offset项、没有待估计的参数时,lrm无法正确生成后续流程依赖的sformula对象。glm没有这个限制,因此仅含offset的模型能正常运行,而lrm会报错。

替代方案代码验证

该替代方案逻辑正确,可实现bootstrap验证需求,具体分析如下:

  • 函数参数符合要求:fBootMetrics的参数匹配boot包的要求,第一个参数接收原始数据,第二个参数接收bootstrap样本的索引,能正确生成bootstrap样本。
  • 模型拟合正确:使用glm(Death ~ 0 + offset(2 * Age), ...)去掉截距项,适配仅含固定offset的模型场景,拟合逻辑合理。
  • 验证指标计算正确:通过rms::val.prob分别计算bootstrap样本上的表观性能、模型在原始数据上的性能,两者差值用于评估乐观偏差,这是bootstrap验证的常规做法。
  • 兼容性处理到位:代码中as.numeric(Death) - 1的处理,兼容Death为因子类型的场景,即使当前测试数据中Death是0/1数值,也不会影响结果。
  • 结果整理正确:最后将bootstrap结果赋值并修改列名,便于后续分析。

综上,该替代方案可有效避开lrm的bug,完成bootstrap验证需求。

内容的提问来源于stack exchange,提问作者Rover Eye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:17:15