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

在R中运行多组Poisson回归时的对比错误排查

解决Poisson回归中contrasts can be applied only to factors with 2 or more levels错误

你的推测方向是对的,问题确实出在ethgp上,但不是全局的因子水平问题——而是在group_by(time, gender, age)拆分出的部分子组里,ethgp只有单一水平。虽然全局来看ethgp有M和NM两个水平,但当你按年份、性别、年龄分组后,某些细分的子组可能只包含其中一个族群的观测(比如2010年40-44岁男性组里全是M族群,没有NM的数据),这时候glm就没法完成族群间的对比计算,直接抛出了对比错误。

下面是具体的验证方法和解决思路:

1. 先确认哪些分组出了问题

你可以用这段代码快速定位所有ethgp水平数不足2的子组:

df %>% 
  group_by(time, gender, age) %>% 
  summarise(ethgp_unique = n_distinct(ethgp), .groups = "drop") %>% 
  filter(ethgp_unique < 2)

运行后会列出所有符合条件的子组,比如某年份+性别+年龄组合下只有M族群的数据,这些就是导致报错的根源。

2. 解决办法:根据需求选择处理方式

方式一:过滤掉无效子组(推荐)

如果这些只有单一族群的子组对你的分析没有价值,可以直接在建模前过滤掉,只保留包含两个族群的子组:

Poisson_test <- df %>% 
  group_by(time, gender, age) %>% 
  filter(n_distinct(ethgp) >= 2) %>%  # 仅保留有完整族群数据的子组
  do({
    model = glm(asr_round ~ relevel(ethgp, ref = 2), family = "poisson", data = .)
    data.frame(nlRR_MNM = coef(model)[[2]], SE_MNM = summary(model)$coefficients[,2][2])
  })

方式二:保留所有子组并标记缺失值

如果你需要保留所有分组(比如后续要做可视化或补全),可以在do函数里加入判断逻辑,给单水平子组返回NA或自定义标记:

Poisson_test <- df %>% 
  group_by(time, gender, age) %>% 
  do({
    # 检查当前子组的ethgp水平数
    if(n_distinct(.$ethgp) < 2){
      data.frame(nlRR_MNM = NA, SE_MNM = NA)
    } else {
      model = glm(asr_round ~ relevel(ethgp, ref = 2), family = "poisson", data = .)
      data.frame(nlRR_MNM = coef(model)[[2]], SE_MNM = summary(model)$coefficients[,2][2])
    }
  })

补充说明

为什么全局检查ethgp是2水平还会报错?因为group_by之后,每个子组都是独立的小数据集,glm是针对每个小数据集单独建模的——只有当某个子组里同时存在M和NM两个族群时,才能计算两者的率比和置信区间,单一水平的子组没有对比的基础,自然会触发对比错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:51:42