R中使用case_when为嵌套数据框追加模型附加向量及多模型写法优化
嵌套数据框定制回归模型的实现方案
原有代码的常见问题
- 原代码中
case_when分支直接赋值并列多元素list("year", "hour")的写法不符合函数返回规则:case_when要求所有分支返回同结构、同长度的结果,这种写法会把单分组的两个附加项拆成两个平行的列表元素,导致后续数据结构错位。 - 硬写长串
case_when分支维护17-20组规则时,容易出现判断条件重叠、漏写默认分支导致NA值的问题。
可直接复用的实现流程
- 第一步:规范附加项字段的存储结构
把每个分组对应的附加变量存为单元素list,元素本身是字符向量,修正后的赋值代码如下:
library(tidyverse) library(purrr) library(nycflights13) flights <- sample_n(flights, 1000) nested <- flights %>% group_by(origin, dest) %>% nest() # 修正add_in的结构:每个分支返回长度为1的list,内部存对应分组的附加变量向量 nested <- nested %>% mutate( add_in = case_when( origin == "EWR" & dest == "CVG" ~ list(c("year", "hour")), origin == "EWR" & dest == "LAX" ~ list(c("year", "dep_delay")), # 为未匹配到的分组设置默认空附加项,避免NA报错 .default = list(c()) ) )
- 第二步:批量拼接无语法错误的完整回归公式
用update函数基于固定基础公式生成对应分组的完整公式,避免硬拼字符串出现公式语法错误:
# 公式拼接辅助函数 build_full_formula <- function(base_rhs, extra_vars) { base_formula <- as.formula(paste("airtime ~", base_rhs)) if (length(extra_vars) == 0) { return(base_formula) } # 把附加变量追加到基础公式的右侧项中 update(base_formula, reformulate(c(attr(terms(base_formula), "term.labels"), extra_vars), response = "airtime")) } # 批量生成每个分组的完整公式 nested <- nested %>% mutate( full_formula = map( .x = add_in, .f = ~build_full_formula(base_rhs = "distance + carrier", extra_vars = .x) ) )
- 第三步:批量运行分组回归模型
nested <- nested %>% mutate( model = map2( .x = data, .y = full_formula, .f = ~lm(formula = .y, data = .x) ) )
多分组规则的简洁优化方案
针对需要配置17-20组不同附加项的场景,不要把所有判断逻辑硬编码在case_when中,可通过独立映射表关联的方式简化维护:
- 先单独建一份分组-附加项的映射表,把所有17-20组的规则统一存在表里,后续增删改规则只需要修改这张表,不需要调整主流程代码:
# 独立维护的映射表,后续补全所有17-20组规则即可 extra_rule_map <- tibble( origin = c("EWR", "EWR", "组1origin值", "组2origin值"), dest = c("CVG", "LAX", "组1dest值", "组2dest值"), add_in = list(c("year", "hour"), c("year", "dep_delay"), c("组1附加变量"), c("组2附加变量")) )
- 直接通过分组键把映射表和嵌套表做左连接,替换原来的长
case_when逻辑:
nested <- nested %>% left_join(extra_rule_map, by = c("origin", "dest")) %>% # 给没有匹配到规则的分组补空向量,避免后续拼接报错 mutate(add_in = map(add_in, ~if (is.null(.x)) c() else .x))
实现过程中的注意事项
- 所有附加变量的列名必须和对应嵌套子数据集的列名完全一致,否则运行模型时会出现找不到对应列的报错。
- 不要用直接拼接字符串的方式生成公式,很容易出现尾部多余
+、变量名转义的语法问题,优先使用formula家族的函数做公式更新。 - 列表结构的字段取值时要注意层级,确保取出的是对应分组的所有附加变量集合,不要拆成平行的列表元素造成遍历错位。
内容的提问来源于stack exchange,提问作者Stat.Enthus
相关产品推荐
相关产品推荐

