R中mad函数与手动计算均值绝对偏差(MAD)的差异及统一方法
均值绝对偏差计算差异原因与修正方法
核心差异说明
你的两种计算方式本质是在计算不同的统计量:
- 手动代码计算的是标准均值绝对偏差(Mean Absolute Deviation):公式为 $\frac{1}{n}\sum|y-\bar{y}|$,直接衡量数据围绕均值的平均离散程度。
- R自带的
mad()函数,即使你指定了center=mean(y),默认逻辑依然是:计算每个值与中心值的绝对偏差 → 取这些偏差的中位数 → 乘以缩放因子1.4826(用于和正态分布标准差对齐)。这和你手动计算的“绝对偏差的均值”完全不是同一个指标。
哪种计算正确?
取决于你的需求:
- 如果要的是数据围绕均值的平均绝对偏差,手动计算的结果是正确的。
- 如果要的是R默认定义的中位数绝对偏差(带缩放),那
mad()的结果是它自身定义下的正确值。
调整方法(让结果一致)
方法1:修改mad()相关代码,匹配手动计算的结果
直接用手动计算的逻辑即可,没必要用mad()函数,因为它的核心逻辑是基于中位数的。示例代码:
data %>% filter(x1 == "A", x2 == "B") %>% group_by(x1, x2) %>% summarise(mean_abs_dev = sum(abs(y - mean(y))) / n())
如果要批量计算所有x1和x2的组合,去掉filter即可:
data %>% group_by(x1, x2) %>% summarise(mean_abs_dev = sum(abs(y - mean(y))) / n())
方法2:修改手动代码,匹配R默认mad()的结果
按照mad()的逻辑,计算围绕中位数的绝对偏差的中位数,再乘以缩放因子:
# 和mad(y)结果一致 data %>% filter(x1 == "A", x2 == "B") %>% group_by(x1, x2) %>% summarise(r_mad = median(abs(y - median(y))) * 1.4826) # 和你原来的mad(y, center=mean(y))结果一致 data %>% filter(x1 == "A", x2 == "B") %>% group_by(x1, x2) %>% summarise(r_mad_mean = median(abs(y - mean(y))) * 1.4826)
额外提示
你的原代码里先group_by(x1, x2)再filter,其实filter已经限定了唯一的x1和x2组合,此时group_by没有实际分组作用,可以去掉或者调换顺序(先filter再group_by)。
内容的提问来源于stack exchange,提问作者raven
相关产品推荐
相关产品推荐

