You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R的lm函数估计多类别下组间直接均值差异?

问题

需要用R中的lm函数估计多类别下处理组与对照组的均值差异(即A_treat - A_control、B_treat - B_control、C_treat - C_control)。目前用y~Categ:Group -1能得到各组单独均值,但用y~Categ*Group -1时,仅A类的差异正确,其余为相对差异,需要调整公式或找到更简便的方法。

示例数据与代码

## 创建数据,A组处理与对照组差异为0.5
Categ <- rep(LETTERS[1:3], times=400)
Group <- rep(c("Control", "Treat"), each = 600)

set.seed(123)
y <- as.numeric(as.factor(Categ))+
  rnorm(length(Group)) +
  ifelse(Categ=="A" & Group =="Treat",rnorm(mean=0.5, length(Group)),0)

df <- data.frame(Categ, Group, y)

## 估计各组单独均值
reg_full <- lm(y~Categ:Group -1, data=df)
coef(reg_full)
#> CategA:GroupControl CategB:GroupControl CategC:GroupControl   CategA:GroupTreat 
#>            1.002340            1.976993            3.085993            1.363267 
#>   CategB:GroupTreat   CategC:GroupTreat 
#>            2.039785            3.016188

## 尝试估计组间差异,但结果不符合预期
reg_diff <- lm(y~Categ*Group -1, data=df)
coef(reg_diff)
#>            CategA            CategB            CategC        GroupTreat 
#>         1.0023399         1.9769931         3.0859931         0.3609268 
#> CategB:GroupTreat CategC:GroupTreat 
#>        -0.2981345        -0.4307316

## 期望得到的直接差异:处理组减对照组的均值差
coef(reg_full)[4:6]-coef(reg_full)[1:3]
#> CategA:GroupTreat CategB:GroupTreat CategC:GroupTreat 
#>         0.3609268         0.0627923        -0.0698048
 
## 当前得到的结果是相对差异
coef(reg_diff)[4:6]
#>        GroupTreat CategB:GroupTreat CategC:GroupTreat 
#>         0.3609268        -0.2981345        -0.4307316
解决方案

方法1:用嵌套公式直接估计组内差异

使用Categ/Group -1的公式,本质是拟合Categ + Categ:Group -1,其中Categ:Group的系数就是每个类别下处理组与对照组的直接差异:

model <- lm(y ~ Categ/Group - 1, data = df)
coef(model)

输出中CategA:GroupTreat、CategB:GroupTreat、CategC:GroupTreat的系数就是对应类别Treat - Control的均值差,和你期望的结果完全一致。

方法2:用分组对比工具直接提取差异

借助emmeans包可以更直观地提取每个类别下的组间差异,同时给出统计显著性:

# 先拟合标准交互模型(不需要去掉截距)
df$Group <- relevel(factor(df$Group), ref = "Control")
model <- lm(y ~ Categ * Group, data = df)

# 提取每个类别下处理组与对照组的对比结果
library(emmeans)
emmeans(model, pairwise ~ Group | Categ)$contrasts

方法3:手动构造对比矩阵计算差异

如果不想用额外包,可以基于全均值模型构造对比矩阵,直接计算目标差异:

reg_full <- lm(y ~ Categ:Group - 1, data = df)

# 构造对比矩阵:每行对应一个类别Treat - Control的对比
contrasts <- matrix(
  c(-1, 0, 0, 1, 0, 0,   # A_Treat - A_Control
    0, -1, 0, 0, 1, 0,   # B_Treat - B_Control
    0, 0, -1, 0, 0, 1),  # C_Treat - C_Control
  nrow = 3, byrow = TRUE,
  dimnames = list(c("A_Treat-Control", "B_Treat-Control", "C_Treat-Control"),
                  names(coef(reg_full)))
)

# 计算差异及显著性
library(multcomp)
summary(glht(reg_full, linfct = contrasts))

方法4:分组计算均值差(最简方式)

用dplyr直接按类别分组计算均值差,适合快速查看结果:

library(dplyr)
df %>%
  group_by(Categ, Group) %>%
  summarise(mean_y = mean(y), .groups = "drop") %>%
  tidyr::pivot_wider(names_from = Group, values_from = mean_y) %>%
  mutate(treat_control_diff = Treat - Control)

如果需要统计检验,可嵌套t.test:

df %>%
  group_by(Categ) %>%
  summarise(
    diff = t.test(y ~ Group)$estimate[2] - t.test(y ~ Group)$estimate[1],
    p_value = t.test(y ~ Group)$p.value,
    .groups = "drop"
  )

内容的提问来源于stack exchange,提问作者Matifou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:20:26