# Stata：不同函数形式的半弹性计算-margins

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

New！ `lianxh` 命令发布了：

`. ssc install lianxh`

`. help lianxh`

⛳ Stata 系列推文：

Source：Using the margins command with different functional forms: Proportional versus natural logarithm changes. -Link-

## 1. 命令简介

`margins` 命令可以进行边际预测，以及边际效应计算，并且通过 `expression()` 选项，`margins` 可以用于任何函数形式。在本文中，我们将展示在线性模型和非线性模型中，如何计算协变量变化导致的结果变量的变化比例 (半弹性)。

## 2. 二元变量的线性模型

``````. webuse lbw, clear
. regress bwt age i.ui

Source |       SS           df       MS      Number of obs   =       189
-------------+----------------------------------   F(2, 186)       =      8.63
Model |  8484309.72         2  4242154.86   Prob > F        =    0.0003
Residual |  91430988.9       186  491564.456   R-squared       =    0.0849
Total |  99915298.6       188  531464.354   Root MSE        =    701.12
------------------------------------------------------------------------------
bwt | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |      9.439      9.678     0.98   0.331       -9.653      28.531
1.ui |   -569.193    143.966    -3.95   0.000     -853.208    -285.177
_cons |   2809.271    233.138    12.05   0.000     2349.337    3269.205
------------------------------------------------------------------------------

. margins, eydx(age ui)

Average marginal effects                                   Number of obs = 189
Model VCE: OLS
Expression: Linear prediction, predict()
ey/dx wrt:  age 1.ui
------------------------------------------------------------------------------
|            Delta-method
|      ey/dx   std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |      0.003      0.003     0.97   0.331       -0.003       0.010
1.ui |     -0.208      0.057    -3.65   0.000       -0.321      -0.096
------------------------------------------------------------------------------
Note: ey/dx for factor levels is the discrete change from the base level.
``````

``````. gen propage = _b[age]/(_b[_cons] + _b[age]*age + _b[1.ui]*ui)
. sum propage

Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
propage |        189     .003225    .0002682   .0029186   .0039631
``````

ui 导致 bw 的变化程度计算代码如下：

``````. preserve
. replace ui = 0
. predict bwthat0
. replace ui = 1
. predict bwthat1
. gen propui = (bwthat1 - bwthat0)/bwthat0 // 错误的计算

. gen lnbwt0  = ln(bwthat0)
. gen lnbwt1  = ln(bwthat1)
. gen propui2 = lnbwt1 - lnbwt0           // 正确的计算
. sum propui propui2
. restore

Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
propui |        189    -.187989    .0030706  -.1935099  -.1760018
propui2 |        189   -.2082484    .0037771  -.2150636  -.1935868
``````

`margins, eydx()` 命令使用对数的方法，因为该方法具有更好的数值特性。如果结果变量本身就是以对数形式存在，例如：

## 3. 分类变量的线性模型

``````. reg bwt age i.race

Source |       SS           df       MS      Number of obs   =       189
-------------+----------------------------------   F(3, 185)       =      3.41
Model |  5239114.38         3  1746371.46   Prob > F        =    0.0186
Residual |  94676184.2       185  511763.158   R-squared       =    0.0524
Total |  99915298.6       188  531464.354   Root MSE        =    715.38
------------------------------------------------------------------------------
bwt | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |      6.147     10.069     0.61   0.542      -13.717      26.011
race |
Black  |   -366.394    160.569    -2.28   0.024     -683.176     -49.612
Other  |   -287.294    115.484    -2.49   0.014     -515.128     -59.460
_cons |   2953.688    255.247    11.57   0.000     2450.119    3457.257
------------------------------------------------------------------------------

. margins, expression((_b[2.race]*2.race + _b[3.race]*3.race)/(_b[_cons]+_b[age]*age)) dydx(race)

Average marginal effects                                   Number of obs = 189
Model VCE: OLS
Expression: (_b[2.race]*2.race + _b[3.race]*3.race)/(_b[_cons]+_b[age]*age)
dy/dx wrt:  2.race 3.race
------------------------------------------------------------------------------
|            Delta-method
|      dy/dx   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
race |
Black  |     -0.118      0.051    -2.34   0.019       -0.217      -0.019
Other  |     -0.093      0.036    -2.58   0.010       -0.163      -0.022
------------------------------------------------------------------------------
Note: dy/dx for factor levels is the discrete change from the base level.
``````

``````. gen double propblack = _b[2.race]/(_b[_cons] + _b[age]*age)
. gen double propother = _b[3.race]/(_b[_cons] + _b[age]*age)
. sum propblack propother

Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
propblack |        189   -.1183368    .0012359  -.1205344  -.1134239
propother |        189   -.0927893    .0009691  -.0945124  -.0889371
``````

## 4. 非线性模型

``````. probit low age i.race

Probit regression                                       Number of obs =    189
LR chi2(3)    =   6.62
Prob > chi2   = 0.0850
Log likelihood = -114.02581                             Pseudo R2     = 0.0282
------------------------------------------------------------------------------
low | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |     -0.025      0.020    -1.26   0.209       -0.063       0.014
race |
Black  |      0.454      0.288     1.58   0.114       -0.110       1.019
Other  |      0.343      0.213     1.61   0.107       -0.074       0.760
_cons |     -0.120      0.486    -0.25   0.805       -1.072       0.832
------------------------------------------------------------------------------

. margins, expression((normal(_b[_cons]+_b[age]*age+_b[2.race]*2.race + _b[3.race]*3.race) ///
>     -normal(_b[_cons] + _b[age]*age))/normal(_b[_cons] + _b[age]*age)) dydx(race)

Average marginal effects                                   Number of obs = 189
Model VCE: OIM
Expression: (normal(_b[_cons]+_b[age]*age+_b[2.race]*2.race + _b[3.race]*3.race)
-normal(_b[_cons] + _b[age]*age))/normal(_b[_cons] + _b[age]*age)
dy/dx wrt:  2.race 3.race
------------------------------------------------------------------------------
|            Delta-method
|      dy/dx   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
race |
Black  |      0.663      0.502     1.32   0.187       -0.321       1.646
Other  |      0.487      0.365     1.33   0.182       -0.229       1.203
------------------------------------------------------------------------------
Note: dy/dx for factor levels is the discrete change from the base level.
``````

``````. webuse dollhill3, clear
. poisson deaths smokes i.agecat, exposure(pyears)

Poisson regression                                      Number of obs =     10
LR chi2(5)    = 922.93
Prob > chi2   = 0.0000
Log likelihood = -33.600153                             Pseudo R2     = 0.9321
------------------------------------------------------------------------------
deaths | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
smokes |      0.355      0.107     3.30   0.001        0.144       0.565
agecat |
45–54  |      1.484      0.195     7.61   0.000        1.102       1.866
55–64  |      2.628      0.184    14.30   0.000        2.267       2.988
65–74  |      3.350      0.185    18.13   0.000        2.988       3.713
75–84  |      3.700      0.192    19.25   0.000        3.323       4.077
_cons |     -7.919      0.192   -41.30   0.000       -8.295      -7.543
ln(pyears) |      1.000  (exposure)
------------------------------------------------------------------------------

. margins, expression((exp(_b[smokes]*smokes+_b[2.agecat]*2.agecat+_b[3.agecat]*3.agecat      ///
>     +_b[4.agecat]*4.agecat+_b[5.agecat]*5.agecat+_ b[_cons])*pyears                         ///
>     -exp(_b[smokes]*smokes+_ b[_cons])*pyears)/(exp(_b[smokes]*smokes+_b[_cons])*pyears))   ///
>     dydx(agecat)

Average marginal effects                                    Number of obs = 10
Model VCE: OIM
Expression: (exp(_b[smokes]*smokes+_b[2.agecat]*2.agecat+_b[3.agecat]*3.agecat
+_b[4.agecat]*4.agecat+_b[5.agecat]*5.agecat+_ b[_cons])*pyears
-exp(_b[smokes]*smokes+_ b[_cons])*pyears)/(exp(_b[smokes]*smokes+_b[_cons])*pyears)
dy/dx wrt:  2.agecat 3.agecat 4.agecat 5.agecat
------------------------------------------------------------------------------
|            Delta-method
|      dy/dx   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
agecat |
45–54  |      3.411      0.861     3.96   0.000        1.724       5.097
55–64  |     12.839      2.543     5.05   0.000        7.856      17.823
65–74  |     27.517      5.270     5.22   0.000       17.188      37.846
75–84  |     39.451      7.776     5.07   0.000       24.211      54.691
------------------------------------------------------------------------------
Note: dy/dx for factor levels is the discrete change from the base level.
``````

## 5. expression 选项

`margins, expression()` 中的函数形式可以根据需要灵活设定。让我们回到 probit 回归。

``````. webuse lbw, clear
. probit low c.age##i.race

Probit regression                                       Number of obs =    189
LR chi2(5)    =   8.16
Prob > chi2   = 0.1475
Log likelihood = -113.25455                             Pseudo R2     = 0.0348
------------------------------------------------------------------------------
low | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |     -0.033      0.027    -1.24   0.215       -0.086       0.019
race |
Black  |     -0.971      1.282    -0.76   0.449       -3.483       1.541
Other  |      0.433      1.044     0.41   0.678       -1.613       2.478
race#c.age |
Black  |      0.065      0.056     1.15   0.249       -0.046       0.176
Other  |     -0.005      0.045    -0.10   0.917       -0.093       0.083
_cons |      0.090      0.652     0.14   0.891       -1.189       1.368
------------------------------------------------------------------------------

. margins, eydx(age)

Average marginal effects                                   Number of obs = 189
Model VCE: OIM
Expression: Pr(low), predict()
ey/dx wrt:  age
------------------------------------------------------------------------------
|            Delta-method
|      ey/dx   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
age |     -0.032      0.023    -1.36   0.174       -0.078       0.014
------------------------------------------------------------------------------
``````

`expression()` 选项中，对于像线性预测这样的事情，不需要写出表达式。因此，上述比例变化可以通过如下方式计算得到：

``````. margins, expression((_b[age] + _b[2.race#c.age]*2.race + _b[3.race#c.age]* ///
>     3.race)*normalden(predict(xb)) / normal(predict(xb)))

Predictive margins                                         Number of obs = 189
Model VCE: OIM
Expression: (_b[age] + _b[2.race#c.age]*2.race + _b[3.race#c.age]*
3.race)*normalden(predict(xb))/normal(predict(xb))
------------------------------------------------------------------------------
|            Delta-method
|     Margin   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
_cons |     -0.032      0.023    -1.36   0.174       -0.078       0.014
------------------------------------------------------------------------------
``````

``````. quietly margins r.race, expression((_b[age] + _b[2.race#c.age]*2.race       ///
>     + _b[3.race#c.age]*3.race)*normalden(predict(xb))/normal(predict(xb)))  ///
>     at(age=(14(5)50))
. quietly marginsplot, noci ytitle("expression in -margins-")
``````

## 6. 相关推文

Note：产生如下推文列表的 Stata 命令为：
`lianxh 边际效应, m`

`ssc install lianxh, replace`

## 相关课程

### 最新课程-直播课

• Note: 部分课程的资料，PPT 等可以前往 连享会-直播课 主页查看，下载。

### 关于我们

• Stata连享会 由中山大学连玉君老师团队创办，定期分享实证分析经验。
• 连享会-主页知乎专栏，700+ 推文，实证分析不再抓狂。直播间 有很多视频课程，可以随时观看。
• 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标，输入简要关键词，以便快速呈现历史推文，获取工具软件和数据下载。常见关键词：`课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法`

✏ 连享会-常见问题解答：
https://gitee.com/lianxh/Course/wikis

New！ `lianxh``songbl` 命令发布了：

`. ssc install lianxh`

`. help lianxh`