*! version 1.1.7 03apr2020 Ben Jann & Simon Seiler
help udiff

Title

udiff -- Generalized unidiff model for individual-level data

Syntax

Simple syntax:

udiff depvar xvars layervar [if] [in] [weight] [,
options ]

Advanced syntax:

udiff depvar term [term ...] [controlvars] [if] [in] [weight] [,
options ]

where term is a unidiff term specified as

(xvars layervar)
or
(xvars <- layervars)
or
(layervars -> xvars)

xvars must be unique across unidiff terms, layervars may be repeated; parentheses may be
omitted if there are no control variables and if only one unidiff term is specified.

Main
cfonly estimate constant-fluidity model instead of unidiff model

constraints(numlist) apply specified linear constraints

baseoutcome(#) value of depvar that will be the base outcome

noconstant suppress constant term

SE/Robust
vce(vcetype) vcetype may be oim,
robust, cluster clustvar, bootstrap, or
jackknife

robust synonym for vce(robust)

cluster(clustvar) synonym for vce(cluster clustvar)

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

allequations report results for all equations; by default only the unidiff parameters are displayed

eform report coefficients in exponentiated form

noheader suppress header display above coefficient table

display_options standard display options

coeflegend display legend instead of statistics

noisily display output from initial constant-fluidity model

Maximization
maximize_options maximization options

xvars, layervars, and controlvars may contain factor variables; see fvvarlist.

svy and mi estimate are supported; see prefix.

fweights, aweights, iweights, and pweights are allowed; see help weight.

predict and other postestimation commands are available after udiff; see below.

estat rescale computes rescaled unidiff parameters after udiff; see below.

estat lambda computes lambda coefficients after udiff; see below.

estat kappa computes kappa indices after udiff; see below.

Description

udiff estimates parameters of the so-called unidiff model (Erikson
and Goldthorpe 1992), also known as the log-multiplicative layer effect
model (Xie 1992), which is often used to study differences in
intergenerational class mobility between birth cohorts or countries.

The original unidiff model has been expressed as a log-linear model of cell
frequencies in a three-way contingency table (origin by destination by
cohort or country). The model, however, can also be expressed at the
individual-level (similar to a multinomial logit model). udiff estimates such a
re-expressed unidiff model for individual-level data. Furthermore, it generalized the
model to allow for multiple layers and non-categorical predictors. For details see
Methods and Formulas below. For an implementation
of the classic log-linear unidiff model for aggregate data see Pisati (2000).

depvar is the (categorical) destination variable (e.g. class of
respondent).

xvars specifies the origin variable(s) (e.g. class of
respondent's parents). Typically, xvars is a single
categorical variable specified as i.varname, although multiple
variables as well as continuous variables are allowed.

layervars specifies the layer variable(s) to be interacted with
xvars. Typically, layervars is a single categorical variable
specified as i.varname (e.g. countries or birth-cohort
categories), although multiple variables as well as continuous variables
are allowed. For example, specify (xvars <-
c.cohort##c.cohort) to model the unidiff scaling factor
as a quadratic function of variable cohort. Likewise, if your data
contains information on countries and birth cohorts, you could type
(xvars <- i.country i.cohort) to include
separate unidiff parameters for both dimensions. Furthermore, you could
type (xvars <- i.country##i.cohort)
to include unidiff parameters for all country-cohort combinations.

controllvars are control variables whose effects are assumed to be
constant across layers.

Options

cfonly causes the constant-fluidity model to be reported instead
of the unidiff model. Estimation of the unidiff model will be skipped.

constraints(numlist) applies linear constraints to
the estimation. numlist specifies the constraints by number, after
they have been defined using the constraint command. An
example is provided below.

baseoutcome(#) specifies the value of depvar to be treated as the base
outcome. The default is to choose the most frequent outcome.

noconstant suppresses the constant (outcome-specific intercepts)
in the model.

vce(vcetype) specifies the type of variance estimation to be used
to determine the standard errors. vcetype may be oim,
robust, cluster clustvar, bootstrap, or
jackknife; see [R] vce_option.

robust is a synonym for vce(robust).

cluster(clustvar) is a synonym for vce(cluster clustvar).

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

allequations reports results for all equations of the model. By default,
only the first equation containing the unidiff parameters is displayed.

eform displays the coefficients in exponentiated form. That is, for each coefficient,
exp(b) rather than b is displayed, and standard errors and
confidence intervals are transformed accordingly.

noheader suppresses the header above the coefficient table
that displays the final log-likelihood value, the number of observations,
and the unidiff significance test.

display_options are standard display options; see
[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.

noisily displays the mlogit output of the initial
constant-fluidity model. By default, the initial model is not displayed.

maximize_options are maximization options such as iterate() or
difficult. See [R] maximize. These options will only
be applied to the unidiff model, but not to the initial constant-fluidity model.

Postestimation commands

Usual postestimation commands such as predict, test, estat,
lincom, nlcom, margins, or suest are available
after udiff. Details on estat and predict are as follows.

Note that, after a model that has been estimated using the svy
prefix, estat rescale, estat lambda, and estat kappa have to be specified as

. udiff_estat subcmd

where subcmd is rescale, lambda, or kappa.

estat rescale

estat rescale [numlist] [, post level(#) display_options ]

Report rescaled unidiff parameters using the normalization suggested by
Xie (1992). The normalization is only supported for unidiff terms that contain
a single categorical layer variable specified as i.varname
(factor variable). The normalization is such that the sum of the squared
parameters equals 1 (within each unidiff term).

numlist specifies the unidiff terms to be included; this is only
relevant if a model contains multiple unidiff terms. The default is to
include all unidiff terms found in the model. To only include, say, the
second unidiff term, type estat rescale 2.

post causes the rescaled results to be posted in e(b) and e(V). This
will clear out the previous estimation results. Without the post option, the results
are stored in r(b) and r(V); see Saved results below.

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

display_options are standard display options; see
[R] estimation options.

estat lambda

estat lambda [#] [, stdize eform compact post level(#) display_options ]

Report lambda coefficients for unidiff term # (if # is omitted,
the first unidiff term is used). estat lambda only supports unidiff terms that contain
a single categorical layer variable and a single categorical predictor, both specified
as i.varname (factor variable). See Pisati (2000) for a definition
of the lambda coefficients.

stdize requests standardized lambda coefficients. The default is to
report raw lambda coefficients.

eform reports the results in exponentiated form.

compact requests that the lambda coefficients be displayed in a
two-way table with one column per outcome level. Standard errors will not be displayed
in this case. The default is to display the coefficients in a one-way
table including standard errors and confidence intervals.

post causes the lambda coefficients to be posted in e(b) and e(V). This
will clear out the previous estimation results. Without the post option, the results
are stored in r(b) and r(V); see Saved results below.

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

display_options are standard display options; see
[R] estimation options.

estat kappa

estat kappa [#] [, post level(#) display_options ]

Report kappa indices coefficients for unidiff term # (if # is omitted,
the first unidiff term is used). estat kappa only supports unidiff terms that contain
a single categorical layer variable and a single categorical predictor, both specified
as i.varname (factor variable). See Pisati (2000) for a definition
of the kappa indices.

post causes the kappa indices to be posted in e(b) and e(V). This
will clear out the previous estimation results. Without the post option, the results
are stored in r(b) and r(V); see Saved results below.

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

display_options are standard display options; see
[R] estimation options.

predict

predict [type] newvar [if] [in] [, xb equation(equation) ]

predict [type] newvar [if] [in], pr [ outcome(outcome) ]

predict [type] {stub* | newvarlist} [if] [in],
scores [ equation(equation) ]

xb calculates linear predictions for the equation specified by
equation(). xb is the default unless pr or scores
is specified. If equation() is omitted, linear predictions are calculated
for the first equation.

equation(equation) specifies the equation for which linear
predictions are to be calculated. equation can be an equation name, or
an equation index specified as #1, #2, etc. Option
equation() is not allowed with pr.

pr calculates predicted probabilities for the outcome specified by
outcome(). If outcome() is omitted, predicted probabilities are
calculated for the first outcome.

outcome(outcome) specifies the outcome for which predicted
probabilities are to be calculated. outcome can be an
outcome value, or an outcome index specified as #1, #2, etc. Option
outcome() is only allowed with pr.

scores calculates equation-level score variables (first derivative
of the log likelihood). If equation() is omitted, score variables
are generated for all equations (one variable per equation; if k is
the number of outcomes, then the number of equations is equal to (k-1)*2+1).

Examples

Basic example
Normalized unidiff parameters
Lambda coefficients and kappa indices
Specifying constraints
Testing model fit
Continuous origin variables
Multiple unidiff terms
Continuous layer variables
Control variables

Basic example

The unidiff model in Example 2 in Pisati (2000) can be reproduced as follows:

. use http://www.stata.com/stb/stb55/sg142/example2.dta, clear
. udiff son i.father i.country [fweight=obs]

Using advanced syntax we could type

. udiff son (i.father <- i.country) [fweight=obs]
or
. udiff son (i.country -> i.father) [fweight=obs]

A likelihood-ratio test against the constant-fluidity model is included in the
header of the output table. In the example, the test is highly significant and confirms that
there are differences in the unidiff parameters between the countries.

By default, udiff omits the base category from the output
(Australia in this example) and displays the unidiff parameters in logarithmic form. To
include the base category in the output, specify baselevels; to
report unidiff parameters as multipliers, add the eform option:

. udiff, eform baselevels

Furthermore, by default only the unidiff scaling parameters are reported. To
report all parameters of the model, specify option all:

. udiff, all

Normalized unidiff parameters

To obtain rescaled unidiff parameters using the normalization suggested
by Xie (1992), you can apply command estat rescale after
model estimation:

. use http://www.stata.com/stb/stb55/sg142/example2.dta, clear
. udiff son i.father i.country [fweight=obs], eform base
. estat rescale

Note that estat rescale is only supported for unidiff terms
that contain a single categorical layer variable.

Lambda coefficients and kappa indices

To obtain lambda coefficients (see Pisati 2000) you can apply command
estat lambda after
model estimation:

. use http://www.stata.com/stb/stb55/sg142/example1.dta, clear
. udiff son i.father i.country [fweight=obs], eform base
. estat lambda, stdize eform compact

The compact option has been specified to display the coefficients
in a two-way table. This means that standard errors are not
shown. Omit the compact option if you are interested in the standard
errors or confidence intervals.

The kappa indices, which are based on standardized lambda coefficients, can
be obtained as follows:

. estat kappa

Note that estat lambda and kappa are
only supported for unidiff terms
that contain a single categorical layer variable and a single categorical
predictor.

Specifying constraints

In case of empty cells or similar problems, it may be necessary to specify
constraints for the model to converge. Using the same data as above, assume
that the combinations of father = "NonManual" and son = "Farm" is missing:

. use http://www.stata.com/stb/stb55/sg142/example2.dta, clear
. replace obs = 0 if son==3 & father==1

To make udiff converge in this example, we can set the parameter
for "NonManual" in the psi-equation for "Farm" to zero (while at the same time
making sure that "NonManual" is not used as the base category). The following
commands would do:

. constraint 1 [Psi_3]: 1.father
. udiff son ib2.father i.country [fweight=obs], allequations constraints(1)

Testing model fit

To test the fit of the unidiff model, a likelihood-ratio test against a
saturated model can be performed, where the saturated model is a
fully-interacted multinomial logit. A significant test statistic would
indicate, that the saturated model fits the data significantly better than the
unidiff model. An example is as follows:

. use http://www.stata.com/stb/stb55/sg142/example1.dta, clear
. udiff son i.father i.country [fweight=obs]
. estimates store udiff
. mlogit son i.father##i.country [fweight=obs]
. lrtest udiff ., force

Option force is needed because different estimation commands have been
used to estimate the two models.

Be aware that the likelihood-ratio test is only valid in case of simple
random sampling. Do not use the test with complex samples, i.e., if
sampling weights or the svy prefix have been specified.

Continuous origin variables

Assume that, apart from the categorical information on father's class,
your data also contains a continuous origin variable such as father's ISEI score
(fisei). Such information could easily be included in the model by adding the
variable to the list of predictors in the unidiff term:

. udiff son (i.father fisei <- i.country)

Multiple unidiff terms

Assume your data also contains information on mothers. You could include this
information in the unidiff model, for example, as follows:

. udiff son (i.father i.mother <- i.country)

In this case, a single unidiff scaling factor would be used for both the effects of
fathers and the effects of mothers. To use different unidiff factors and thus
allow the effects of father and mothers to vary differently across countries, you
could type:

. udiff son (i.father <- i.country) (i.mother <- i.country)

Continuous layer variables

The layer variable(s) do not need to be categorical. For example, if you have
individual-level data containing information on the birth years
of the respondents, you could model the layer effects
as a parabolic function of the birth year to analyze how social mobility changes over
time. To avoid convergence issues it is
a good idea to center the birth years at a date that actually exists in the data. For
example, define cohort = (birth year - 1980) and then type

. udiff son (i.father <- c.cohort##c.cohort)

Likewise, you could model the layer effects in terms of country characteristics:

. use http://www.stata.com/stb/stb55/sg142/example2.dta, clear
. udiff son (i.father <- develop socdem i.east i.asia) [fweight=obs]

Statistical inference may not be credible in this example and we might want to
cluster on countries:

. udiff son (i.father <- develop socdem i.east i.asia) [fweight=obs], cluster(country)

No value for the joint Wald test of the unidiff parameters (i.e. the
test against the constant-fluidity model) is reported in this case due to the
way how ml (the underlying command used for model estimation) determines the
degrees of freedom for the test. You can obtain the test using the
test command after model estimation:

. test [Phi]

However, note that the number of countries is small. Cluster-robust
standard errors may be inconsistent in such a setting (a general recommendation
is that the number of clusters should be at least 40 or 50).

Control variables

Assume that the age structure (or distribution of birth years) is different
across countries and you want to take account of that in your analysis. You could,
for example, type

. udiff son (i.father <- i.country) age

In this way a an age effect that is common to all countries is included
in the model. You could, of course, also use a more complex specification,
such as, e.g.,

. udiff son (i.father <- i.country) c.age##c.age

Methods and formulas

The unidiff model

The unidiff model is typically used to study differences in
intergenerational social mobility between birth cohorts or countries. Let
mu(x,y,z) be the cell frequencies in a three-way table of X (origin
class, e.g. class of parents) by Y (destination class, e.g. class of
children) by Z (e.g. cohort). Lowercase x, y, and z denote the
levels of X, Y, and Z. In a saturated log-linear model the cell
frequencies are parametrized as

ln mu(x,y,z) = a + a(x) + a(y) + a(z) + a(x,y) + a(x,z) + a(y,z) + a(x,y,z)

where a is an overall intercept capturing the average cell frequency,
a(x), a(y), and a(z) are factors capturing the marginal distributions
of X, Y, and Z, a(x,y), a(x,z), and a(y,z)
capture two-way associations, and a(x,y,z) captures the three-way
association. For example, if X, Y, and Z are independent from each other,
a(x,y), a(x,z), a(y,z), and a(x,y,z) will be zero for
all x, y, and z. Likewise, if the association between X and Y is
constant over cohorts, a(x,y,z) will be zero for all x, y, and z,
such that

ln mu(x,y,z) = a + a(x) + a(y) + a(z) + a(x,y) + a(x,z) + a(y,z)

This is the so-called constant-fluidity model. The saturated
model accurately describes the data, but has too many parameters
to be informative; the constant-fluidity model is too
simplistic because it assumes away any change in relative mobility. The unidiff
model takes a middle ground in that it allows the association between X and Y
to vary with Z, but places a specific restriction on the form of this
variation. In particular, the unidiff model introduces a scaling factor
b(z) such that

ln mu(x,y,z) = a + a(x) + a(y) + a(z) + a(x,z) + a(y,z) + a(x,y) * b(z)

That is, the unidiff model assumes that there is a common association pattern
between X and Y, but the "strength" of the pattern can differ across
cohorts.

Re-expression at the individual level

Traditionally, the unidiff model has been estimated from tabular data.
However, the model (or, at least, the interesting part of it) can also be
expressed such that it takes the form of a regression model fitted to
individual-level data. From a perspective with Y as the "dependent"
variable, the saturated log-linear model is equivalent to a multinomial
logit of Y on X, Z, and the interaction between X and Z, where X and Z are
treated as factor variables. Likewise, the constant-fluidity model is a
multinomial logit of Y on X and Z, without interaction between X and Z.
Furthermore, the unidiff model is equivalent to a multinomial logit written
as

Pr(Y = y| X, Z) = exp(W'theta(y) + X'psi(y) * exp(Z'phi)) / D

where D is the sum of the expression in the numerator across all levels of
Y, and W is equal to Z augmented by a constant, i.e. W = (1,Z')' (again, X
and Z are treated as factor variables, i.e. think of X and Z as vectors
of dummy variables). theta(y), phi,
and psi(y) are parameter vectors; phi is common to all levels of
Y, theta(y) and psi(y) are level-specific. In this model,
theta(y) represents a(y) and a(y,z) (the marginal
distribution of Y as well as the main effects of Z, i.e. how the marginal
distribution of Y depends on Z), exp(phi) represents b(z) (the
unidiff scaling factors), and psi(y) represents a(x,y) (the
association between X and Y). Terms a(x) (marginal distribution of X),
a(z) (marginal distribution of Z), a(x,z) (association between X
and Z) are not represented in the model (i.e., the model only contains
parameters that are related to Y).

Generalization: multiple unidiff terms

Generally seen, the unidiff model is just a multinomial logit model
that contains a special kind of interaction terms. The model may thus be
useful also for research questions that have nothing to do with social
mobility. Furthermore, the model can be generalized so that it contains
multiple unidiff terms. Let X1 and X2 be two sets of independent
variables, Z1 and Z2 two sets of layer variables, and C a set of
control variables that are not interacted with Z1 or Z2. The model can then be
written as:

Pr(Y = y| X1, Z1, X2, Z2, C) =

exp(W'theta(y) + X1'psi1(y) * exp(Z1'phi1) + X2'psi2(y) * exp(Z2'phi2)) / D

where W = (1, Z1', Z2', C')'. The model can be extended analogously
to accommodate more than two unidiff terms.

Estimation

udiff estimates the unidiff model using ml. To obtain good
starting values, udiff first fits a constant-fluidity model (which is
equivalent to a standard mlogit model ignoring the layer
variables). A test of the unidiff model against the constant-fluidity model
is included in the output (as an LR test or a Wald test, depending on
context).

As usual in a multinomial logit, the coefficients are set to zero for one
of the levels of Y to identify the model. Furthermore, as is usual for factor variables,
phi is set to zero for one of the levels of Z if Z is a categorical variable. exp(phi)
then expresses the unidiff scaling factors with respect to this base category.

Estimating the unidiff model from individual-level data is more demanding
than fitting the model to a contingency table (although note that, for
efficient computation, fweights can be used on collapsed data),
but it brings about enhanced flexibility. For example, it is easily
possible to include continuous (rather than categorical) origin and layer
variables, control variables whose effects as assumed constant over cohorts
can be taken into account (by including them in W), and standard errors for
the parameter estimates are readily available (including support for
sampling weights or other characteristics of a complex survey design).

Saved results

udiff stores results as described in [R] ml,
as well as the following elements:

Scalars

e(k_out) number of outcomes

e(ibaseout) index of the base outcome

e(k_unidiff) number of unidiff terms

e(k_eform) number of equations to be affected by the eform option

Macros

e(cmd) udiff

e(predict) udiff_p

e(estat_cmd) udiff_estat

e(cfonly) cfonly or empty

e(layervars) names of layer variables; if e(k_unidiff)=1

e(layervars#) names of layer variables of #th unidiff term; if e(k_unidiff)>1

e(xvars) names of independent variables; if e(k_unidiff)=1

e(xvars#) names of independent variables of #th unidiff term; if e(k_unidiff)>1

e(controlvars) names of control variables

e(eqnames) names of equations

e(out) values of depvar

e(baseout) value of depvar treated as the base outcome

e(out_labels) value labels of depvar (if available)

Without the post option, estat rescale, estat lambda, and estat kappa store the following
results in r():

Scalars

r(N) number of observations

Matrices

r(b) coefficients

r(V) variance matrix

r(lambda) compact representation coefficients (estat lambda only)

Without the post option, estat rescale,
estat lambda, and
estat kappa
store the following results in e():

Scalars

r(N) number of observations

r(N_clust) number of clusters (if vcetype is cluster)

r(k_eq) number of equations

e(k_eform) number of equations to be affected by the eform option

Macros

e(cmd) udiff_estat

e(subcmd) rescale or lambda

e(estat_cmd) udiff_estat

e(title) title used in output

e(vce) vcetype as specified when calling udiff

e(vcetype) title used to label Std. Err.

e(clustvar) name of cluster variable

e(properties) b V

Matrices

e(b) coefficients

e(V) variance matrix

r(lambda) compact representation coefficients (estat lambda only)

References

Erikson, R., J.H. Goldthorpe. 1992. The Constant Flux: A Study of Class
Mobility in Industrial Societies. Oxford: Oxford University Press.

Pisati, M. 2000. sg142: Uniform
layer effect models for the analysis of differences in two-way associations. Stata
Technical Bulletin 55: 33-47.

Xie, Y. 1992. The Log-Multiplicative Layer Effect Model for Comparing Mobility
Tables. American Sociological Review 57(3): 380–395.

Authors

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

Simon Seiler, University of Bern, simon.seiler@icer.unibe.ch

Thanks for citing this software as follows:

Jann, B., S. Seiler. 2019. udiff: Stata module to estimate the generalized
unidiff model for individual-level data. Available from
http://ideas.repec.org/c/boc/bocode/s458711.html.