help lnmorhttp://github.com/benjann/lnmor/

Title

lnmor -- Compute marginal (log) odds ratios after model estimation

Syntax -
Description -
Options -
Examples -
Stored results -
References -
Author -
Also see

Syntax

lnmor termlist [,
options
]

where termlist is

term [term ...]

and term may be:

(1) a simple varname

(2) an indicator variable specification such as
i.varname, ibn.varname, or
i(2 3 4).varname ; see fvvarlist

(3) an interaction specification of a continuous variable with itself, such
as c.varname##c.varname;
see fvvarlist; interactions containing multiple variables or
interactions involving indicator variables or are not allowed

Consecutive elements referring to the same variable (e.g.,
2.cat 3.cat 4.cat or x1 c.x1#c.x1 c.x1#c.x1#c.x1)
will be merged into a single term (as long as they are of the same type). Likewise,
varlist specifications such as x* or x1-x5, or groups
such as i.(var1 var2) will be split into separate terms, one
for each variable. In general, each term must refer to a distinct
variable (that is, variables may not be repeated across terms) and all
specified variables must appear among the covariates of the model to
which lnmor is applied.

options

Main
dx[(spec)] use derivative-based
evaluation for continuous terms

delta[(#)] compute discrete change effects, not
derivatives

centered use symmetric definition of discrete change effects

normalize normalize discrete change effects

at(spec) estimate results at
specified values of covariates

subsample(spec) restrict
evaluation to subsample

nodots suppress progress dots

post post results in e()

SE/Robust
vce(vcetype) vcetype may be
bootstrap or jackknife

nose do not estimate SEs

ifgenerate(spec) store influence functions

rifgerate(spec) store recentered influence functions

ifscaling(spec) scaling of (recentered) IFs

replace allow replacing existing variables

Reporting
level(#) set confidence level; default is level(95)

or report odds ratios

noheader suppress table header

notable suppress coefficients table

display_options standard display option

coeflegend display legend instead of statistics

Seldom used
miopts(options) options to be
passed through to mi estimate

kmax(#) maximum number of levels without coarsening

atmax(#) maximum number of patterns allowed in at()

constant report constant from fracreg

[no]tbal enforce/prevent balancing in fracreg

nowarn suppress variable type warning messages

Description

lnmor computes (adjusted) marginal odds ratios after logit or
probit (possibly including the svy or mi estimate
prefix) using G-computation. By default, lnmor obtains marginal ORs
by applying fractional logit (fracreg) to averaged
counterfactual predictions from the original model. Alternatively, for
continuous predictors, specify option dx() to compute
derivative-based marginal ORs. For methods and formulas see
Jann and Karlson (2023).

lnmor requires moremata to be installed on the system. Type
ssc install moremata.

Options

dx[(spec)] uses a derivative-based approach
to compute results for continuous terms. By default, lnmor generates
population-averaged counterfactual predictions for each level of a variable
and then computes the marginal OR by applying fractional logit
(fracreg) to these averaged predictions. Alternatively, if
dx() is specified, results will be obtained by taking derivatives of
population-averaged counterfactual predictions. This is only relevant for
continuous terms that do not include interactions. That is, dx() will
be ignored for factor variable terms and interaction terms. dx() will
also be ignored if a term is specified as continuous in lnmor, but
the relevant variable has been included as a factor variable in the
original model. spec may be one of the following.

average report the average derivative across the distribution
of the variable; this is the default

atmean report the derivative at the mean of the variable

observed report a derivative based on a marginal shift in
observed values

. same as observed

numlist report derivative at each specified level

levels report derivative at each observed level; not allowed if
termlist contains multiple terms affected by dx()

delta[(#)] requests that dx() computes
discrete change effects rather than derivatives. Discrete change effects
are computed as the difference in population-averaged log odds at
t+# and t, where t is the treatment value at which
the effect is to be evaluated. delta without argument is equivalent
to delta(1) (unit change effect). delta() implies dx().

Discrete change effects are not defined if # is 0. In this case, lnmor
will compute (log) odds rather than (log) odds ratios. That is, you can
specify delta(0) to obtain levels rather than effects (options
centered and normalize will be ignored in this case).

centered requests that discrete change effects are computed
using predictions at t+#/2 and t-#/2 rather than
at t+# and t. centered is only relevant if delta()
has been specified.

normalize divides discrete change effects by #. normalize
is only relevant if delta() has been specified.

at(spec) reports results with covariates fixed at specific values. The
syntax of spec is

varname = numlist [varname = numlist ...]

Computations will be repeated for each pattern of combinations of the
specified covariate values. You can also type at(varlist) to use the levels
found in the data for each variable instead of specifying custom values. In
any case, the variables specified in at() must be different from the
variables specified in termlist. Furthermore, only variables
that appear as covariates in the original model are allowed.

subsample(spec) restricts the evaluation of the marginal odds ratio
to a subsample (i.e. counterfactual predictions will averaged over the
specified subsample only). The syntax of spec is

[varname] [if]

The subsample is defined by observations for which varname!=0 (and not
missing) and for which the if condition applies.

nodots suppresses the progress dots.

post stores results in e() rather than in r(). post
has no effect if vce(bootstrap) or vce(jackknife) is specified,
or if lnmor is applied after svy; results will always be stored
in e() in these cases. If lnmor is applied after
mi estimate, option post behaves in the same way as option
post in mi estimate.

vce(vcetype) specifies the variance estimation method. The
default is to compute robust standard errors based on influence functions (taking
account of clustering if the original model includes clustering). Use option
vce() to request replication-based standard errors; vcetype may be
bootstrap or jackknife; see vce_option. If replication-based
standard errors are requested, lnmor will reestimate the original model
within replications. Option vce() is not allowed after svy
or mi estimate, or if the model has been estimates with fweights.

nose suppresses calculation of the VCE and standard errors. The
variance matrix will be set to zero in this case. To save computer time,
nose is implied by vce(bootstrap) and vce(jackknife)
or if lnmor is applied after svy with replication-based VCE. Option
nose is not allowed after svy with linearization-based VCE or after
mi estimate.

ifgenerate(spec) stores the influence functions of the estimates. Either
specify a list of new variables names, or specify stub*, in which
case the new variables will be named
stub1, stub2, etc. Option ifgenerate() is not
allowed with vce(bootstrap) or vce(jackknife), after svy
with replication-based VCE, or after mi estimate. ifgenerate()
has no effect if nose is specified.

rifgenerate(spec) stores the recentered influence functions; see the description
of ifgenerate(). Only one of ifgenerate() and rifgenerate()
is allowed.

ifscaling(spec) determines the scaling of the stored (recentered) influence
functions. spec can be total (scaling for analysis by
total) or mean (scaling for analysis by mean). Default is
ifscaling(total).

replace allows to overwrite existing variables.

level(#) specifies the confidence level, as a percentage, for
confidence intervals. The default is level(95) or as
set by set level.

or reports the estimated coefficients transformed to odds ratios,
that is, exp(b) rather than b. Standard errors and confidence intervals are
similarly transformed. This option affects how results are displayed, not
how they are estimated. or may be specified at estimation or when
replaying previously estimated results that were stored in e() using
option post.

noheader suppresses the display of the table header.

notable suppresses the display of the coefficients table.

display_options are display options as documented in
[R] Estimation options.

coeflegend specifies that the legend of the coefficients and how to
specify them in an expression be displayed rather
than displaying the statistics for the coefficients.

miopts(options) specifies options to be passed through to
mi estimate. This is only allowed when running lnmor after
a model to which mi estimate has been applied.

kmax(#) sets the maximum number of levels (distinct values) that are
allowed for continuous treatments. If a variable has more levels,
lnmor will provide approximate results based on linearly binned
levels. The default is kmax(100).

atmax(#) sets the maximum number of patterns (combinations of values) that is
allowed in at(). The default is atmax(50).

constant includes the constant of the fractional logit in the
results vector. The default is to remove the constant. Including
the constant may be helpful, for example, if you want to generate
predictions from nonlinear terms. constant cannot be
combined with dx() and is not allowed if termlist contains
multiple terms.

[no]tbal decides whether to weight all treatment levels in the
fractional logit equally or whether to weight them by observed
frequencies. The default is to weight by observed frequencies unless the
fractional logit is saturated (i.e., if all levels are covered by indicator
variables in term), in which case the weights do not change the
result. Specify tbal or notbal to override the default behavior.

nowarn suppresses the warning messages that are displayed if the types
of the specified terms do not match the types of the
relevant variables in the original model.

Examples

Basic usage
Nonlinear effects
Bootstrap standard errors
Survey estimation
Multiple imputation

Basic usage

The following example illustrates how the adjusted marginal odds ratio can be
different from the conditional odds ratio:

unadjusted marginal odds ratio
. webuse lbw
. logit low i.smoke, or vce(robust)
. lnmor i.smoke, or

conditional odds ratio
. logit low i.smoke i.race age lwt ptl ht ui, or

adjusted marginal odds ratio
. lnmor i.smoke, or

Results can be obtained for several variables in one call:

. lnmor i.smoke i.race age lwt, or

Use option at() to explore interactions:

. logit low i.smoke i.race age lwt ptl ht ui i.smoke#i.race, or

. lnmor i.smoke, at(race) or

Use ibn.varname to obtain marginal odds by level rather than odds ratios:

. lnmor ibn.smoke, at(race) or

Note that, for categorical predictors, a combination of margins and nlcom
can be used to replicate the results by lnmor:

. logit low i.smoke i.race age lwt ptl ht ui, vce(robust)

. lnmor i.smoke, or

. margins, at(smoke=(0 1)) post vce(unconditional)

. nlcom (smoke:(logit(_b[2._at]) - logit(_b[1._at]))), post

. ereturn display, eform(Odds Ratio)

Nonlinear effects

Nonlinear effects can, for example, be explored using the dx()
option. Example:

. sysuse nlsw88

. logit union i.south grade c.grade#c.grade c.grade#c.grade#c.grade age

. lnmor grade, dx(levels) post

The output reports the marginal (log) odds ratio at different levels of
grade. Graphically, the pattern looks as follows (type
ssc install coefplot to make coefplot available on your system):

. estimates store dx
. coefplot dx, at(levels) yline(0) yti(ln OR)

The effect appears to be positive at the bottom and at the top, and negative
in the middle.

A similar analysis could also be performed by specifying interaction terms
when calling lnmor:

. logit union i.south grade c.grade#c.grade c.grade#c.grade#c.grade age

. lnmor grade c.grade#c.grade c.grade#c.grade#c.grade

Qualitatively, results from the two approaches are very similar, as can be
illustrated as follows:

. local function `=el(r(b),1,1)' + 2*`=el(r(b),1,2)'*x + 3*`=el(r(b),1,3)'*x^2

. coefplot dx, at(levels) yline(0) yti(ln OR) addplot(function `function', range(0 18))

As is evident, the effect function from the second approach matches the
point estimates from the first approach very well.

Bootstrap standard errors

By default, lnmor reports robust standard errors based on
influence-functions. If you want to obtain replication-based standard
errors, specify vce(bootstrap) or vce(jackknife) with
lnmor, not with the original command (it does not hurt to specify
these options with the original command, but lnmor will not pick them
up). An example is as follows:

. webuse lbw
. logit low i.smoke i.race age lwt ptl ht ui, or
. lnmor i.smoke i.race age lwt, vce(bootstrap) or

To lnmor reestimates the original model within the single
replications.

Survey estimation

lnmor can be applied after survey estimation, i.e. after a model
to which the svy prefix has been applied.

. webuse nhanes2f
. svy: logit highbp i.female i.race height weight age, or
. lnmor i.female i.race, or

This also works with replication-based VCE.

. webuse nhanes2brr
. svy: logit highbp i.female i.race height weight age, or
. lnmor i.female i.race, or

Multiple imputation

lnmor can be applied after a model to which multiple imputation
has been applied.

. webuse mheart1s20
. mi estimate, or: logit attack i.smokes age bmi i.hsgrad i.female
. lnmor i.smokes, or
. lnmor i.smokes, or miopts(dots mcerror)

Stored results

lnmor stores the following in r():

Scalars

r(N) number of observations

r(N_clust) number of clusters

r(N_subsmp) number of observations in subsample

r(sum_w) sum of weights

r(sum_w_subsmp) sum of weights in subsample

r(k_eq) number of equations in r(b)

r(df_r) r(N)-1 or r(N_clust)-1

r(nterms) number of terms

r(k#) number evaluation levels used for term #

r(dx#) whether dx() has been applied to term #

r(delta) value of delta(), if specified

r(rank) rank of r(V)

Macros

r(cmd) lnmor

r(cmdline) command as typed

r(est_cmd) e(cmd) from original estimation results

r(est_cmdline) e(cmdline) from original estimation results

r(title) title in estimation output

r(depvar) name of dependent variable

r(term#) specification of term #

r(name#) variable name of term #

r(type#) factor, variable, or interaction; type of term #

r(dxtype) average, atmean, observed, levels, or empty

r(dxlevels) levels specified in dx()

r(centered) centered or empty

r(normalize) normalize or empty

r(atnames) variable names from at()

r(subsample) specification from subsample()

r(tbal) tbal, notbal, or empty

r(wtype) weight type

r(wexp) weight expression

r(clustvar) name of cluster variable

r(vce) vcetype specified in vce()

r(vcetype) title used to label Std. err.

r(ifgenerate) names of variables containing IFs

r(iftype) IF or RIF (or empty)

r(ifscaling) total or mean (or empty)

Matrices

r(b) coefficient vector

r(V) variance-covariance matrix of the estimators

r(at) matrix of values from at()

r(levels#) values and counts of evaluation levels used for term #

r(levels) vector matching r(b) containing levels from dx(levels) or dx(numlist)

r(table) information from the coefficient table

If post is specified, results are stored in e() rather than
r() and function e(sample) that marks the estimation sample is
added. An exception is r(table), which will remain in r(); see
help _coef_table or ereturn for details in r(table).

Likewise, results are stored in e() rather than r()
if vce(bootstrap) or vce(jackknife) is specified
or if lnmor is applied after svy or mi estimate.

lnmor can be applied repeatedly even if results are stored in
e() (which overwrites the original model); lnmor
will refit the original model if necessary.

References

Jann, Ben, Kristian Bernt Karlson. 2023. Estimation of marginal odds ratios. University
of Bern Social Sciences Working Papers 44. Available from
https://ideas.repec.org/p/bss/wpaper/44.html.

Author

Ben Jann, University of Bern, ben.jann@unibe.ch

Thanks for citing this software as

Jann, B. 2022. lnmor: Stata module to compute marginal odds
ratios after model estimation. Available from http://github.com/benjann/lnmor/.

Also see

Online: help for
logit, probit, ipwlogit (if installed), riflogit (if installed)