如何在R中复现Stata默认margins命令的输出结果?
在R中复现Stata默认
margins命令的输出 我完全懂你和伙伴们的困扰——R的margins包默认输出的是平均边际效应(AME),对应Stata里的margins, dydx(*);但你们课程里用的是Stata不带任何选项的默认margins,这俩算的根本不是一回事,难怪试了半天没成功。下面我一步步给你们讲清楚怎么在R里复现:
先搞懂Stata默认margins到底算的是什么
Stata敲margins不加任何选项时,默认计算的是调整后预测值(adjusted predictions),具体规则是:
- 连续型协变量:取它们的样本均值
- 分类型协变量:如果是因子变量,会单独计算每个水平下的预测值;如果没声明为因子,就取参考水平或均值(看变量类型)
- 最终输出的是这些协变量取值组合下的预测响应值,可不是边际效应哦
R里的复现方法(分工具介绍)
我用大家熟悉的mtcars数据集+线性回归做例子,你可以直接套到自己的课程数据上:
1. 用emmeans包(最推荐,和Stata行为最匹配)
emmeans专门用来处理这类调整后预测值,语法也很直观:
# 先加载需要的包 library(stats) # 基础线性回归用这个 library(emmeans) # 拟合模型:mpg受车重wt和气缸数cyl(分类变量)影响 model <- lm(mpg ~ wt + factor(cyl), data = mtcars)
- 如果Stata里你只敲了
margins(没指定变量,算总体预测均值),对应R代码:
# 计算所有协变量取均值/分类变量各水平平均后的总体预测值 emmeans(model, ~ 1)
- 如果Stata里敲的是
margins cyl(看气缸数每个水平的预测值),对应R代码:
# 计算cyl每个水平下的调整后预测值(wt自动取样本均值) emmeans(model, ~ cyl)
2. 用你熟悉的margins包调整参数
要是你更习惯用margins,可以通过at参数指定协变量取值,复现Stata的逻辑:
library(margins) # 指定wt取均值,cyl取所有水平,计算响应尺度的预测值 margins(model, at = list(wt = mean(mtcars$wt), cyl = unique(mtcars$cyl)), type = "response")
这里type = "response"确保输出的是原始响应尺度的数值,和Stata默认一致。
3. 手动计算(帮你理解底层逻辑)
对于线性模型,你也可以手动算,结果和上面完全一致:
# 先拿到wt的样本均值 mean_wt <- mean(mtcars$wt) # 生成新数据集:wt固定为均值,cyl取4/6/8三个水平 new_data <- data.frame(wt = mean_wt, cyl = factor(c(4,6,8))) # 计算预测值 predict(model, newdata = new_data)
关键注意点
- 分类变量一定要转成
factor:Stata里如果把变量声明为因子,margins会自动处理每个水平;R里也一样,模型里的分类变量必须是factor类型,不然会被当成连续变量算,结果肯定对不上。 - 模型类型适配:如果是广义线性模型(比如logistic回归)、混合效应模型,只需要调整
emmeans或margins的type参数(比如type = "response"对应响应尺度,type = "link"对应链接尺度),和Stata的predict()选项对应上就行。
你可以拿课程里的数据集试一下,应该就能完美匹配Stata默认margins的输出了~
内容的提问来源于stack exchange,提问作者Steen Harsted




