R语言:使用mutate调用多输出自定义回归函数时结果重复的问题排查与解决方案
问题成因与解决方案
为什么所有行返回相同结果?
问题出在向量化操作和全局变量依赖的结合上:
- 当你在
mutate里直接调用reggers(comp_id)时,comp_id是整个列(长度为5的向量),而非逐行的单个公司ID。 - 你的
reggers函数里用filter(comp_id == x),这里的x是整个向量,==会做向量化匹配,等价于comp_id %in% x——也就是筛选出了所有公司的全部数据,然后跑了一次全局回归,所以所有行都返回这个全局回归的结果。 - 单独运行时你传的是单个ID,函数筛选对应公司的数据,所以结果和全局回归不同。
解决方案
这里有两种简洁的方法实现逐行计算:
方法1:用rowwise()强制逐行处理
在mutate前加上rowwise(),让comp_id逐行传入函数:
library(tidyverse) companies <- data.frame(comp_id = 1:5) individuals <- data.frame(id = 1:100, comp_id = sample(1:5, 100, replace = T), age = sample(18:67, 100, replace = T), wage = sample(1700:10000, 100, replace = T)) reggers <- function(x){ df <- individuals %>% filter(comp_id == x) formula <- wage ~ age regression <- lm(formula, df) res <- list(coeff = summary(regression)$coefficient[2,1], p = summary(regression)$coefficients[2,4], r2 = summary(regression)$r.squared) return(res) } # 修改后的代码 companies %>% rowwise() %>% mutate(data = list(reggers(comp_id))) %>% unnest_wider(data) %>% ungroup() # 记得取消rowwise,避免后续操作受影响
方法2:用purrr::map_dfr(更简洁高效)
map_dfr会自动遍历comp_id的每个元素,将函数结果整合成数据框,无需手动unnest:
companies %>% mutate(map_dfr(comp_id, reggers))
额外优化:让函数更健壮
你的函数依赖全局变量individuals,这在复杂项目里容易出错。可以把数据集作为参数传入函数:
reggers <- function(x, data){ sub_df <- data %>% filter(comp_id == x) formula <- wage ~ age regression <- lm(formula, sub_df) # 直接返回tibble,比list更方便后续处理 tibble( coeff = summary(regression)$coefficient[2,1], p = summary(regression)$coefficients[2,4], r2 = summary(regression)$r.squared ) } # 调用时传入数据集 companies %>% mutate(map_dfr(comp_id, reggers, data = individuals))
这样修改后,函数不再依赖全局变量,复用性和安全性都更高,同时也能完美实现你需要的逐公司计算需求。
内容的提问来源于stack exchange,提问作者business_of_ferrets
相关产品推荐
相关产品推荐

