如何在R的glm.nb函数的as.formula(paste0())中添加offset变量?
在R语言glm.nb中动态构建公式并添加offset的正确方法
问题场景
尝试通过as.formula(paste0(...))动态构建公式,在glm.nb中添加offset变量时出现多种错误,示例代码及报错如下:
示例代码
z <- c("T3", "T3", "T3", "T2", "T2", "T3", "T3", "T2", "T2", "T2", "T3", "T3", "T3", "T3", "T2", "T3", "T2", "T2", "T1", "T3", "T3", "T2", "T2", "T2", "T2", "T2", "T2", "T3", "T2", "T3", "T2", "T2", "T2", "T2", "T3", "T3", "T2", "T2", "T3", "T3", "T3", "T3", "T3", "T3", "T3", "T2", "T3", "T2", "T3", "T3", "T3", "T2", "T1", "T3", "T3", "T3", "T3", "T2", "T3", "T3", "T2", "T2", "T2", "T2", "T2", "T3", "T2", "T3", "T2", "T3", "T3", "T3", "T3", "T2", "T2", "T2", "T2", "T2", "T2", "T3", "T3", "T3", "T3", "T3", "T3", "T2", "T2", "T2", "T2", "T2", "T3", "T3", "T3", "T3", "T3", "T2", "T3", "T2", "T3", "T2", "T2", "T2", "T2", "T3", "T3", "T3", "T2", "T2", "T3", "T2", "T3", "T3", "T2", "T2") x <- c("B-", "B-", "B+", "B+", "B-", "B-", "B+", "B-", "B-", "B-", "B-", "B-", "B-", "B-", "B+", "B-", "B-", "B-", "B+", "B-", "B+", "B+", "B-", "B-", "B+", "B-", "B+", "B+", "B-", "B-", "B+", "B+", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B+", "B-", "B-", "B+", "B+", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B-", "B-", "B+", "B+", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B-", "B+", "B+", "B+", "B-", "B-", "B+", "B-", "B-", "B-", "B-", "B-", "B-", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B+", "B+", "B-", "B+", "B+", "B+", "B-", "B-", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B-", "B-", "B-", "B-", "B-", "B+", "B+", "B-", "B-", "B+", "B+", "B-", "B+", "B+", "B-", "B-", NA ) Y <- c(0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 13, 19, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 0, 2, 0, 0, 6, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0, 0, 0, 3) y1 <- c(1, 3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 1, 0, 5, 0, 2, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 12, 1, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0, 4, 0, 0, 0, 2, 2, 0, 0, 1, 0, 0, 16, 0, 14, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 6, 0, 0, 1, 0, 0, 1, 13) of <- rnorm(114,0,1) data <- data.frame(Y, y1, z, x, of) f1 <- "Y" f2 <- "x * (z) + y1" offset <- data.frame(of) # 错误调用示例 glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(offset)"))), data = data) glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(of)"))), data = data)
报错信息
> glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(offset)"))), data = data) Error in model.frame.default(formula = as.formula(paste0(f1, " ~ ", f2, : invalid type (list) for variable 'offset(offset)' > glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(of)"))), data = data) Error in model.frame.default(formula = as.formula(paste0(f1, " ~ ", f2, : variable lengths differ (found for 'offset(of)')
错误原因分析
- 语法错误:
glm.nb调用中多了一个右括号,导致参数传递结构混乱,这是触发报错的直接原因。 - offset变量类型错误:定义
offset <- data.frame(of)将offset变量设为数据框(列表类型),但offset()函数要求传入数值向量,因此offset(offset)会报类型不匹配错误。 - 行匹配问题:
x变量包含1个NA值,拟合模型时model.frame会自动剔除含NA的行(剩余113行),若公式中直接引用原向量of,未同步处理NA,会导致向量长度(114)与处理后数据长度(113)不匹配。
解决方法
方法1:修正语法,直接引用数据框中的向量列
修正glm.nb的括号错误,直接使用数据框中已有的of列(向量类型),此时model.frame会自动同步处理NA行,确保长度匹配:
# 修正后的正确调用 model1 <- glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(of)")), data = data) summary(model1)
方法2:使用glm.nb的offset参数(推荐)
无需在公式字符串中拼接offset,直接通过glm.nb的offset参数传入向量,代码更简洁且不易出错:
# 构建基础公式 base_formula <- as.formula(paste0(f1, " ~ ", f2)) # 传入offset参数,自动匹配数据行 model2 <- glm.nb(base_formula, data = data, offset = of) summary(model2)
方法3:手动清理NA后拟合
若需要手动控制数据清理逻辑,可先剔除含NA的行,再构建公式拟合:
# 剔除所有含NA的行 data_clean <- na.omit(data) # 拟合模型 model3 <- glm.nb(as.formula(paste0(f1, " ~ ", f2, " + offset(of)")), data = data_clean) summary(model3)
内容的提问来源于stack exchange,提问作者Ph.D.Student
相关产品推荐
相关产品推荐

