使用R margins包复制Stata marginlist参数吗?

eci*_*nex 5 r prediction stata marginal-effects

我无法在R中复制Stata margins命令的特定用例: margins var1, over(var2) 我一直在尝试使用marginsR中的包进行复制。

为了提供可重现的示例,我使用了mtcars数据集并将其从R导出到Stata中,因此我们在两个程序中都使用了相同的数据集:

R代码:

library(foreign)
library(margins)
write.dta(mtcars, “mtcars.dta")
Run Code Online (Sandbox Code Playgroud)

Stata代码:

use "mtcars.dta", clear
Run Code Online (Sandbox Code Playgroud)

在两个程序中创建示例线性回归模型

Stata代码:

quietly regress mpg cyl i.am c.wt##c.hp
Run Code Online (Sandbox Code Playgroud)

R代码:

x <- lm(mpg ~ cyl + factor(am) + hp * wt, data = mtcars)
Run Code Online (Sandbox Code Playgroud)

两个程序之间的模型输出(未显示)相同

比较模型中每个变量的平均边际效应表

Stata代码和输出:

margins, dydx(*)

Average marginal effects                          Number of obs   =         32
Model VCE: OLS

Expression   : Linear prediction, predict() dy/dx w.r.t. : cyl 1.am wt hp

------------------------------------------------------------------------------
             |            Delta-method
             |      dy/dx   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         cyl |  -.3708001   .5293674    -0.70   0.490     -1.45893    .7173301
        1.am |  -.0709546   1.374981    -0.05   0.959    -2.897268    2.755359
          wt |  -3.868994   .9170145    -4.22   0.000    -5.753944   -1.984043
          hp |  -.0249882   .0120345    -2.08   0.048    -.0497254    -.000251
------------------------------------------------------------------------------ 
Note: dy/dx for factor levels is the discrete change from the base level.
Run Code Online (Sandbox Code Playgroud)

R代码和输出:

xmarg <- margins(x)
summary(xmarg)

factor     AME     SE       z      p   lower   upper
    am1 -0.0710 1.3750 -0.0516 0.9588 -2.7659  2.6240
    cyl -0.3708 0.5294 -0.7005 0.4836 -1.4083  0.6667
     hp -0.0250 0.0120 -2.0764 0.0379 -0.0486 -0.0014
     wt -3.8690 0.9170 -4.2191 0.0000 -5.6663 -2.0717
Run Code Online (Sandbox Code Playgroud)

如您所见,这两个输出非常相似,就像使用R margins包所期望的那样。

问题1:边际预测超过变量的值

Stata代码和输出:

margins, over(cyl)

Predictive margins                                Number of obs   =         32
Model VCE: OLS

Expression   : Linear prediction, predict()
over         : cyl

------------------------------------------------------------------------------
             |            Delta-method
             |     Margin   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
         cyl |
          4  |   26.56699   .6390379    41.57   0.000     25.25342    27.88055
          6  |   20.04662   .5797511    34.58   0.000     18.85492    21.23831
          8  |   15.02406   .5718886    26.27   0.000     13.84853    16.19959
------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

R代码和输出:

aggregate(fitted~cyl, data = xmarg, FUN = mean)
  cyl   fitted
1   4 26.56699
2   6 20.04662
3   8 15.02406
Run Code Online (Sandbox Code Playgroud)

在上面的两个示例中,R和Stata之间的边际预测相同。但是,是否有一种方法(不需要手动完成),可以像上面的Stata表中那样为每个边际预测生成增量法标准误差?

问题2:特定变量的边际预测:

Stata代码和输出:

margins am

Predictive margins                                Number of obs   =         32
Model VCE    : OLS

Expression   : Linear prediction, predict()

------------------------------------------------------------------------------
             |            Delta-method
             |     Margin   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
          am |
          0  |   20.11945   .6819407    29.50   0.000      18.7177     21.5212
          1  |    20.0485   .9052764    22.15   0.000     18.18767    21.90932
------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

R代码和输出:

aggregate(fitted~am, data = xmarg, FUN = mean)
  am   fitted
1  0 17.14737
2  1 24.39231
Run Code Online (Sandbox Code Playgroud)

在此示例中,我们尝试margins通过在预测后对数据集进行子集化来在命令中复制Stata的“ marginlist”参数。这似乎不是正确的方法。我们如何从Stata复制这些结果?

问题3:一个变量对另一个变量的边际预测

复制此结果是我的主要目标!

Stata代码和输出

margins am, over(cyl)

Predictive margins                                Number of obs   =         32
Model VCE    : OLS

Expression   : Linear prediction, predict()
over         : cyl

------------------------------------------------------------------------------
             |            Delta-method
             |     Margin   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
      cyl#am |
        4 0  |   26.61859   1.246074    21.36   0.000     24.05725    29.17993
        4 1  |   26.54763   .7034599    37.74   0.000     25.10165    27.99362
        6 0  |   20.07703   .6449805    31.13   0.000     18.75125     21.4028
        6 1  |   20.00607   1.144518    17.48   0.000     17.65348    22.35866
        8 0  |    15.0342   .6228319    24.14   0.000     13.75395    16.31445
        8 1  |   14.96324   1.257922    11.90   0.000     12.37754    17.54894
------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

R代码和输出:

aggregate(fitted ~ am + cyl, data = xmarg, FUN = mean)
  am cyl   fitted
1  0   4 22.83306
2  1   4 27.96721
3  0   6 19.06359
4  1   6 21.35732
5  0   8 15.08720
6  1   8 14.64519
Run Code Online (Sandbox Code Playgroud)

如您所见,现在的点估计值已经大不相同,并且再次没有SE表。解决上面的问题1和问题2可能会解决问题3。

Tho*_*mas 3

对于这些问题,您需要预测包,它是margins的一部分。目前无法获得平均预测的标准误差,但您至少可以使用以下方法获得与 Stata 相同的平均预测。

关于 Stata 命令的关键直觉margins如下:

margins x1
Run Code Online (Sandbox Code Playgroud)

相当于

margins, at(x1 = (...))
Run Code Online (Sandbox Code Playgroud)

其中...是 的所有可能值x1。这些表达式中的任何一个都会生成反事实数据集,其中x1数据中的所有情况都固定为给定值,然后对该数据集的临时反事实版本执行模型预测。

over()选项是一个子集化过程:

margins, over(x1)
Run Code Online (Sandbox Code Playgroud)

根据 的值分割数据x1,然后对每个子集进行模型预测。您可以将其与此结合起来at,但考虑起来有点奇怪。例如:

margins, over(x1) at(x2 = (1 2))
Run Code Online (Sandbox Code Playgroud)

将所有观测值固定x2为 1,然后将数据分割为x1,然后为每个子集生成预测,并对它们求平均值。然后它对反事实版本重复此操作,其中x2所有观察值都设置为 2。

在 R 中,prediction::prediction()将为您提供at()使用at参数的等效项。它还会为您提供相当于over()将数据子集传递给data参数的功能。

所以,对于你的问题2

> prediction::prediction(x, at = list(am = c(0,1)))
Average predictions for 32 observations:
 at(am) value
      0 20.12
      1 20.05
Run Code Online (Sandbox Code Playgroud)

对于你的问题3

> prediction::prediction(x, at = list(am = c(0,1)), data = subset(mtcars, cyl == 4))
Average predictions for 11 observations:
 at(am) value
      0 26.62
      1 26.55
> prediction::prediction(x, at = list(am = c(0,1)), data = subset(mtcars, cyl == 6))
Average predictions for 7 observations:
 at(am) value
      0 20.08
      1 20.01
> prediction::prediction(x, at = list(am = c(0,1)), data = subset(mtcars, cyl == 8))
Average predictions for 14 observations:
 at(am) value
      0 15.03
      1 14.96
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,您都无法通过执行predict(x)并聚合预测来复制 Stata 的输出,因为预测是在反事实数据集上发生的。

而且,目前尚未实施差异(截至 2018 年 8 月)。