R语言数据分组求均值时变量顺序致结果异常问题
问题:summarise中变量定义顺序导致计算结果异常
我尝试按年份-技能组计算分组均值,但所有skilled==0的非技能组结果均为NAN,且每年均存在skilled==1和skilled==0的观测值。
初始代码(结果异常):
wage_df <- df %>% filter(!is.na(wage) & !is.na(skilled)) %>% group_by(year) %>% summarise(skilled = mean(wage[skilled == 1]), unskilled = mean(wage[skilled == 0]), total = sum(wage * wtsupp) / sum(wtsupp))
调换变量定义顺序后代码(结果正常):
wage_df <- df %>% filter(!is.na(wage) & !is.na(skilled)) %>% group_by(year) %>% summarise(unskilled = mean(wage[skilled == 0]), skilled = mean(wage[skilled == 1]), total = sum(wage * wtsupp) / sum(wtsupp))
原因分析
核心问题是**summarise中定义新变量时,如果变量名和原数据框的列名重复,后续计算会使用已经被覆盖的新值,而非原数据的原始列值**:
在第一段异常代码中:
- 第一步定义
skilled = mean(wage[skilled == 1])时,用的还是原数据里的skilled列(0/1的分类变量),这一步计算是正确的。 - 第二步计算
unskilled = mean(wage[skilled == 0])时,skilled已经被替换成了前面算出的均值(一个单一数值,不再是原有的0/1分类),此时skilled == 0的判断完全不符合实际数据,自然筛选不出有效观测,最终返回NA。
- 第一步定义
在调换顺序后的代码中:
- 先计算
unskilled,此时用的是原数据的skilled分类列,能正确筛选非技能组的薪资数据并计算均值。 - 后续定义
skilled时即使覆盖了原列,也不会影响已经完成的非技能组计算,所以结果正常。
- 先计算
解决建议
避免在summarise中使用和原数据列名相同的变量名,比如将统计结果重命名为带标识的名称,彻底规避顺序问题:
wage_df <- df %>% filter(!is.na(wage) & !is.na(skilled)) %>% group_by(year) %>% summarise(skilled_mean = mean(wage[skilled == 1]), unskilled_mean = mean(wage[skilled == 0]), total = sum(wage * wtsupp) / sum(wtsupp))
内容的提问来源于stack exchange,提问作者Jianing Shao
相关产品推荐
相关产品推荐

