使用$运算符与dplyr::mutate生成结果不一致的技术咨询
两种数据处理方式导致lme模型系数差异的原因分析
问题重现
用户使用两种方式计算中心化后的sum_lag.gmc,后续运行lme模型得到的系数不一致:
写法1:$运算符赋值
Data_filtered_0 <- Data_filtered_0 %>% dplyr::mutate(sum_lag = lag(sum, n = 1, default = NA)) Data_filtered_0$sum_lag.gmc <- Data_filtered_0$sum_lag - mean(Data_filtered_0$sum_lag, na.rm=T)
写法2:连续使用dplyr::mutate
Data_filtered_0 <- Data_filtered_0 %>% dplyr::mutate(sum_lag = lag(sum, n = 1, default = NA)) %>% dplyr::mutate(sum_lag.gmc = sum_lag - mean(sum_lag, na.rm=T))
模型代码(注:代码中存在变量名笔误tres_rnt和res_rnt,需确认是否为输入错误):
tres_rnt <- lme(sum ~ sum_lag.gmc, random = ~ sum_lag.gmc | accountId, data = Data_filtered_0, na.action="na.exclude") Coefficients <- as.data.frame(coef(res_rnt), col.names=NULL) Coefficients <- tibble::rownames_to_column(Coefficients, "accountId")
核心原因:分组上下文的继承
最可能的差异来源是**Data_filtered_0是否为分组数据框(grouped_df)**:
- 写法1中,
$运算符会直接忽略数据的分组属性,mean(Data_filtered_0$sum_lag, na.rm=T)计算的是整个数据集的全局均值,最终sum_lag.gmc是全局中心化的结果。 - 写法2中,dplyr的链式操作会继承之前的分组上下文(如果
Data_filtered_0是通过group_by(accountId)等操作分组的),此时mean(sum_lag, na.rm=T)会自动按每个分组计算均值,最终sum_lag.gmc是分组内中心化的结果。
两种中心化方式的结果完全不同,直接导致后续lme模型的系数差异。
验证与解决方法
验证分组状态
运行以下代码检查数据是否为分组数据框:is.grouped_df(Data_filtered_0)如果返回
TRUE,即可确认是分组导致的差异。统一处理逻辑
- 若需要全局中心化,写法2中需显式取消分组:
Data_filtered_0 <- Data_filtered_0 %>% dplyr::mutate(sum_lag = lag(sum, n = 1, default = NA)) %>% dplyr::ungroup() %>% # 取消分组,确保mean计算全局均值 dplyr::mutate(sum_lag.gmc = sum_lag - mean(sum_lag, na.rm=T)) - 若需要分组内中心化,写法1需改为分组计算:
Data_filtered_0 <- Data_filtered_0 %>% dplyr::mutate(sum_lag = lag(sum, n = 1, default = NA)) %>% dplyr::group_by(accountId) %>% dplyr::mutate(sum_lag.gmc = sum_lag - mean(sum_lag, na.rm=T)) %>% dplyr::ungroup()
- 若需要全局中心化,写法2中需显式取消分组:
内容的提问来源于stack exchange,提问作者user21579413
相关产品推荐
相关产品推荐

