emmeans()与fct_na_value_to_level()联用的一致性Bug
emmeans() 与 fct_na_value_to_level() 联用下标越界问题分析
先给出最小复现代码,方便复现问题:
library(forcats) library(emmeans) # 构造测试数据 set.seed(123) df <- data.frame( tension = factor(sample(c("low", "medium", "high", NA), 100, replace = TRUE)), strength = rnorm(100, 20, 3) ) # 不指定新层级名,转换NA为因子水平后调用emmeans报错 df$tension_na_level2 <- fct_na_value_to_level(df$tension) model2 <- lm(strength ~ tension_na_level2, data = df) # emmeans(model2, ~ tension_na_level2) # 执行会抛出"indice hors limites"错误 # 指定新层级名,转换后调用emmeans正常 df$tension_na_level1 <- fct_na_value_to_level(df$tension, level = "Missing") model1 <- lm(strength ~ tension_na_level1, data = df) emmeans(model1, ~ tension_na_level1) # 正常输出结果
问题根源拆解
1. forcats两种用法的本质差异
当你不指定level参数时,fct_na_value_to_level()会把NA直接作为因子的一个层级名称——注意这里的层级名是真正的缺失值,不是字符串"NA"。你可以用levels()函数验证:
levels(df$tension_na_level2) # 输出是: [1] "high" "low" "medium" NA
而指定level = "Missing"时,生成的是字符串类型的层级名,所有层级都是合法的非缺失字符串:
levels(df$tension_na_level1) # 输出是: [1] "high" "low" "medium" "Missing"
2. emmeans的索引逻辑缺陷
emmeans在提取模型的因子水平估计值时,依赖可被索引的非缺失层级名称。当因子层级里混有NA作为名称时,emmeans内部尝试通过名称匹配索引对应结果时,NA无法作为有效索引键,直接触发了下标越界的错误。
说白了,这是两个包的处理规则冲突:forcats允许NA当层级名,但emmeans没考虑这种极端情况,导致代码报错。
解决办法
最稳妥:显式指定层级名
调用fct_na_value_to_level()时,一定要通过level参数传一个字符串(比如"Missing"、"NA"),别让它默认生成NA作为层级名。事后补救:修改已生成的因子层级
如果已经生成了含NA层级名的因子,可以手动替换掉这个层级名:
levels(df$tension_na_level2)[is.na(levels(df$tension_na_level2))] <- "NA"
修改后再调用emmeans()就能正常运行了。
内容的提问来源于stack exchange,提问作者doana
相关产品推荐
相关产品推荐

