Appendix 3G: Marginal Odds Ratios

\[AME = \frac{1}{N}\sum_{i = 1}^{N}\left\{\eta(x_{k} = {end}_{i}, \mathbf{x}_{-k} = \mathbf{x}_{-k,i}) - \eta(x_{k} = {start}_{i}, \mathbf{x}_{-k} = \mathbf{x}_{-k,i})\right\}\]

\[MOR = \frac{odds\left[\frac{1}{N}\sum_{i = 1}^{N}\eta(x_{k} = {end}_{i}, \mathbf{x}_{-k} = \mathbf{x}_{-k,i})\right]}{odds\left[\frac{1}{N}\sum_{i = 1}^{N}\eta(x_{k} = {start}_{i}, \mathbf{x}_{-k} = \mathbf{x}_{-k,i})\right]}\]

The example replicates Karlson and Jann (2023) Table 2 and Figure 1 (GSS); the MORs in the figure are from their Table 2:

use "https://tdmize.github.io/data/data/MORs-gss", clear
fre year
year -- GSS YEAR FOR THIS RESPONDENT
-----------------------------------------------------------
              |      Freq.    Percent      Valid       Cum.
--------------+--------------------------------------------
Valid   1976  |        840       6.86       6.86       6.86
        1977  |        906       7.40       7.40      14.27
        1980  |        950       7.76       7.76      22.03
        1982  |       1128       9.22       9.22      31.24
        1984  |        926       7.57       7.57      38.81
        1985  |        999       8.16       8.16      46.97
        1987  |       1157       9.45       9.45      56.43
        1988  |        626       5.11       5.11      61.54
        1989  |        664       5.43       5.43      66.97
        1990  |        610       4.98       4.98      71.95
        1991  |        657       5.37       5.37      77.32
        1993  |        729       5.96       5.96      83.27
        1994  |       1405      11.48      11.48      94.75
        1996  |        642       5.25       5.25     100.00
        Total |      12239     100.00     100.00           
-----------------------------------------------------------
* Logit model (fully interacted with year)
logit racseg c.year##(i.col c.age i.race i.marital c.polviews i.female)
Iteration 0:  Log likelihood = -6860.6371  
Iteration 1:  Log likelihood = -6237.4239  
Iteration 2:  Log likelihood = -6200.5001  
Iteration 3:  Log likelihood = -6200.2352  
Iteration 4:  Log likelihood = -6200.2352  

Logistic regression                                    Number of obs =  12,239
                                                       LR chi2(21)   = 1320.80
                                                       Prob > chi2   =  0.0000
Log likelihood = -6200.2352                            Pseudo R2     =  0.0963

-------------------------------------------------------------------------------
       racseg | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
--------------+----------------------------------------------------------------
         year |     -0.111      0.021   -5.353   0.000       -0.152      -0.071
        1.col |    -12.100     21.661   -0.559   0.576      -54.554      30.354
          age |     -1.430      0.616   -2.322   0.020       -2.637      -0.223
              |
         race |
       black  |    -52.864     38.078   -1.388   0.165     -127.496      21.767
       other  |     -2.587     56.352   -0.046   0.963     -113.034     107.860
              |
      marital |
     widowed  |    -21.443     25.741   -0.833   0.405      -71.895      29.009
    divorced  |     -8.235     23.185   -0.355   0.722      -53.677      37.206
   separated  |    -36.811     42.728   -0.862   0.389     -120.556      46.934
never marr..  |     -7.353     28.690   -0.256   0.798      -63.585      48.879
              |
     polviews |     -0.515      5.754   -0.090   0.929      -11.793      10.762
     1.female |     11.334     15.216    0.745   0.456      -18.488      41.157
              |
   col#c.year |
           1  |      0.006      0.011    0.513   0.608       -0.016       0.027
              |
 c.year#c.age |      0.001      0.000    2.360   0.018        0.000       0.001
              |
  race#c.year |
       black  |      0.026      0.019    1.360   0.174       -0.011       0.064
       other  |      0.001      0.028    0.048   0.962       -0.054       0.057
              |
      marital#|
       c.year |
     widowed  |      0.011      0.013    0.848   0.397       -0.014       0.036
    divorced  |      0.004      0.012    0.358   0.721       -0.019       0.027
   separated  |      0.019      0.022    0.865   0.387       -0.024       0.061
never marr..  |      0.004      0.014    0.260   0.795       -0.025       0.032
              |
       c.year#|
   c.polviews |      0.000      0.003    0.103   0.918       -0.005       0.006
              |
female#c.year |
           1  |     -0.006      0.008   -0.748   0.455       -0.021       0.009
              |
        _cons |    218.501     41.253    5.297   0.000      137.646     299.355
-------------------------------------------------------------------------------
est store rsmod
margins, dydx(col) at(year=(1976(5)1996)) post
Average marginal effects                                Number of obs = 12,239
Model VCE: OIM

Expression: Pr(racseg), predict()
dy/dx wrt:  1.col
1._at: year = 1976
2._at: year = 1981
3._at: year = 1986
4._at: year = 1991
5._at: year = 1996

------------------------------------------------------------------------------
             |            Delta-method
             |      dy/dx   std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
0.col        |  (base outcome)
-------------+----------------------------------------------------------------
1.col        |
         _at |
          1  |     -0.213      0.021   -9.970   0.000       -0.255      -0.171
          2  |     -0.181      0.012  -14.893   0.000       -0.205      -0.157
          3  |     -0.147      0.008  -17.910   0.000       -0.163      -0.131
          4  |     -0.115      0.009  -12.904   0.000       -0.133      -0.098
          5  |     -0.088      0.010   -8.547   0.000       -0.109      -0.068
------------------------------------------------------------------------------
Note: dy/dx for factor levels is the discrete change from the base level.
* Pr() reduction in gap from 76 to 96
lincom _b[1.col:5._at] - _b[1.col:1bn._at]
 ( 1)  - [1.col]1bn._at + [1.col]5._at = 0

------------------------------------------------------------------------------
             | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
         (1) |      0.125      0.028    4.520   0.000        0.071       0.179
------------------------------------------------------------------------------
* % reduction in gap from 76 to 96
nlcom ((_b[1.col:5._at] - _b[1.col:1bn._at])/_b[1.col:1bn._at]) * 100
       _nl_1: ((_b[1.col:5._at] - _b[1.col:1bn._at])/_b[1.col:1bn._at]) * 100

------------------------------------------------------------------------------
             | Coefficient  Std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
       _nl_1 |    -58.509      7.673   -7.625   0.000      -73.548     -43.469
------------------------------------------------------------------------------
library(haven)           # import Stata data and labels
library(dplyr)           # data manipulation
library(ggplot2)         # graphs
library(marginaleffects) # predictions and marginal effects
library(cleanplots)      # graph scheme
cleanplots_defaults()

gss <- read_dta("https://tdmize.github.io/data/data/MORs-gss.dta")

table(gss$year)

1976 1977 1980 1982 1984 1985 1987 1988 1989 1990 1991 1993 1994 1996 
 840  906  950 1128  926  999 1157  626  664  610  657  729 1405  642 
# Treat binary/nominal variables as factors
gss <- gss |>
  mutate(year = as.numeric(year), racseg = as.numeric(racseg),
    col = factor(col, labels = c("No college", "College")), race = as_factor(race),
    marital = as_factor(marital), female = factor(female)) |>
  droplevels()

# Logit model (fully interacted with year)
rsmod <- glm(racseg ~ year * (col + age + race + marital + polviews + female),
  family = binomial(link = "logit"), data = gss)
summary(rsmod)

Call:
glm(formula = racseg ~ year * (col + age + race + marital + polviews + 
    female), family = binomial(link = "logit"), data = gss)

Coefficients:
                            Estimate Std. Error z value Pr(>|z|)    
(Intercept)                2.185e+02  4.125e+01   5.297 1.18e-07 ***
year                      -1.113e-01  2.078e-02  -5.353 8.66e-08 ***
colCollege                -1.210e+01  2.166e+01  -0.559   0.5764    
age                       -1.430e+00  6.159e-01  -2.322   0.0202 *  
raceblack                 -5.286e+01  3.808e+01  -1.388   0.1650    
raceother                 -2.587e+00  5.635e+01  -0.046   0.9634    
maritalwidowed            -2.144e+01  2.574e+01  -0.833   0.4048    
maritaldivorced           -8.235e+00  2.318e+01  -0.355   0.7224    
maritalseparated          -3.681e+01  4.273e+01  -0.862   0.3889    
maritalnever married      -7.353e+00  2.869e+01  -0.256   0.7977    
polviews                  -5.155e-01  5.754e+00  -0.090   0.9286    
female1                    1.133e+01  1.522e+01   0.745   0.4563    
year:colCollege            5.592e-03  1.091e-02   0.513   0.6083    
year:age                   7.324e-04  3.103e-04   2.360   0.0183 *  
year:raceblack             2.607e-02  1.917e-02   1.360   0.1737    
year:raceother             1.353e-03  2.835e-02   0.048   0.9619    
year:maritalwidowed        1.099e-02  1.297e-02   0.848   0.3967    
year:maritaldivorced       4.176e-03  1.167e-02   0.358   0.7206    
year:maritalseparated      1.862e-02  2.152e-02   0.865   0.3869    
year:maritalnever married  3.760e-03  1.445e-02   0.260   0.7947    
year:polviews              2.991e-04  2.898e-03   0.103   0.9178    
year:female1              -5.731e-03  7.666e-03  -0.748   0.4547    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 13721  on 12238  degrees of freedom
Residual deviance: 12400  on 12217  degrees of freedom
AIC: 12444

Number of Fisher Scoring iterations: 5
ames <- avg_comparisons(rsmod, variables = "col", by = "year",
  newdata = datagrid(year = seq(1976, 1996, 5), grid_type = "counterfactual"))
ames

 year Estimate Std. Error      z Pr(>|z|)     S  2.5 %  97.5 %
 1976  -0.2131    0.02138  -9.97   <0.001  75.4 -0.255 -0.1712
 1981  -0.1808    0.01214 -14.89   <0.001 164.2 -0.205 -0.1570
 1986  -0.1470    0.00821 -17.91   <0.001 235.9 -0.163 -0.1309
 1991  -0.1155    0.00895 -12.90   <0.001 124.1 -0.133 -0.0979
 1996  -0.0884    0.01035  -8.55   <0.001  56.1 -0.109 -0.0682

Term: col
Type: response
Comparison: College - No college
# Pr() reduction in gap from 76 to 96
hypotheses(ames, hypothesis = "b5 - b1 = 0")

 Hypothesis Estimate Std. Error    z Pr(>|z|)    S  2.5 % 97.5 %
    b5-b1=0    0.125     0.0276 4.52   <0.001 17.3 0.0706  0.179
# % reduction in gap from 76 to 96
hypotheses(ames, hypothesis = "(b5 - b1) / b1 * 100 = 0")

       Hypothesis Estimate Std. Error     z Pr(>|z|)    S 2.5 % 97.5 %
 (b5-b1)/b1*100=0    -58.5       7.67 -7.62   <0.001 45.2 -73.5  -43.5
// Figure 1 replication from Karlson & Jann 2023
est restore rsmod
(results rsmod are active now)
qui margins col, at(year=(1976(2)1996))
marginsplot, recastci(rline) ciopt(col(*.5) lpat(dash)) ///
    xtitle("Calendar year") legend(order(3 "No college" 4 "College")) ///
    ytitle("Pr(segregation is a right)") ///
    xlabel(1976(5)1996) ylabel(0(.1).55) ///
    title("[3.17.a] Pr(Thinking segregation is a right) over time, by college 
completion", size(medlarge)) ///
    subtitle("Comparing AMEs with marginal ORs") ///
    text(.52 1978 "AME = -0.21" .48 1978 "MOR = 0.37" ///
        .45 1981.5 "AME = -.18" .41 1981.5 "MOR = 0.37" ///
        .38 1986 "AME = -.15" .34 1986 "MOR = 0.38" ///
        .31 1991 "AME = -.12" .27 1991 "MOR = 0.39" ///
        .25 1996 "AME = -.09" .21 1996 "MOR = 0.40")
Variables that uniquely identify margins: year col

Predicted probability of thinking segregation is a right by year for adults with and without college: both decline from 1976 to 1996 and the gap narrows, with the AME shrinking from -0.21 to -0.09 while the MOR stays near 0.37 to 0.40.

# Figure 1 replication from Karlson & Jann 2023
rs_prs <- avg_predictions(rsmod, by = c("year", "col"),
  newdata = datagrid(year = seq(1976, 1996, 2), col = unique, grid_type = "counterfactual"))

ggplot(rs_prs, aes(x = year, y = estimate, color = col)) +
  geom_line() +
  geom_point() +
  geom_line(aes(y = conf.low), linetype = "dashed", alpha = 0.5) +
  geom_line(aes(y = conf.high), linetype = "dashed", alpha = 0.5) +
  annotate("text", x = c(1978, 1978, 1981.5, 1981.5, 1986, 1986, 1991, 1991, 1996, 1996),
    y = c(.52, .48, .45, .41, .38, .34, .31, .27, .25, .21),
    label = c("AME = -0.21", "MOR = 0.37", "AME = -.18", "MOR = 0.37", "AME = -.15",
      "MOR = 0.38", "AME = -.12", "MOR = 0.39", "AME = -.09", "MOR = 0.40")) +
  scale_x_continuous(breaks = seq(1976, 1996, 5), limits = c(1975, 1998)) +
  scale_y_continuous(breaks = seq(0, .5, .1), limits = c(0, .55)) +
  labs(title = "[3.17.a] Pr(Thinking segregation is a right) over time, by college completion",
    subtitle = "Comparing AMEs with marginal ORs",
    x = "Calendar year", y = "Pr(segregation is a right)", color = NULL)

Predicted probability of thinking segregation is a right by year for adults with and without college: both decline from 1976 to 1996 and the gap narrows, with the AME shrinking from -0.21 to -0.09 while the MOR stays near 0.37 to 0.40.

*AME has declined by 58.5% between 1976 and 1996; MOR has barely changed

*My replication of Figure 1 from Karlson and Jann 2023

Thoughts on the marginal odds ratio

  • Karlson and Jann (2023) make a convincing case that the marginal odds ratio has better statistical properties than the odds ratio you obtain by exponentiating the logit coefficients
    • E.g., Better for comparing effects across models
  • While I agree it has nicer properties than a traditional OR—I do not see any reason to prefer it over a ME as a default interpretation strategy
  • Sometimes, multiplicative/ratio effects are of interest (see Risk Ratio section; though I think these cases are rare)
    • However, I can think of no reason to preference a marginal odds ratio interpretation over a risk ratio interpretation in this case
      • Both are multiplicate/ratio effects, but the risk ratio avoids the unnecessary (and confusing) nonlinear transformation into the odds metric
Back to top