*! version 0.5.0 08nov2025

Title

xtvfreg -- Varying fixed effects panel regression with heteroscedastic variance function

Syntax

xtvfreg
depvar
[if] [in]
[weight]
,
groupvar(varname)
panelid(varname)
meanvars(varlist)
varvars(varlist)
[options]

pweights are allowed; see weight.

Model
* groupvar(varname) grouping variable for separate estimations

* panelid(varname) panel identifier variable

* meanvars(varlist) covariates for mean equation

* varvars(varlist) covariates for variance equation

Options
tvar(varname) time variable (optional, currently not used)

converge(real) convergence tolerance; default is converge(1e-6)

maxiter(integer) maximum iterations; default is maxiter(100)

nolog suppress iteration log

table display comparison table of estimates across groups

combined display combined mean and variance equation tables

* groupvar(), panelid(), meanvars(), and varvars() are required.

Description

xtvfreg implements an iterative mean-variance panel regression estimator
that allows both the mean and variance of the dependent variable to be functions
of covariates. The method is based on Mooi-Reci & Liao (2025) and consists of
iteratively estimating:

(1) A mean equation using generalized linear models (GLM) with Gaussian
family and identity link

(2) A variance equation using GLM with Gamma family and log link,
applied to squared within-group (fixed effects) residuals

The algorithm alternates between these two steps, using the estimated variance
from step (2) as analytic weights in step (1), until the change in the
log-likelihood of the variance equation falls below the convergence criterion.

When probability weights (pweights) are specified, they are combined with
the algorithm's analytic variance weights. Specifically, the combined weight used
in the mean equation is pweight/S², where S² is the estimated variance
function. This ensures both the sampling design and heteroscedasticity are
properly accounted for.

The command estimates separate models for each level of the grouping variable,
allowing the mean and variance structures to differ across groups. This is
particularly useful for studying heterogeneity in both location and scale
parameters across subpopulations.

Options

Model

groupvar(varname) specifies the grouping variable. The command loops over
each distinct level of this variable and runs the iterative estimation separately
for each group. This allows the mean and variance parameters to differ across groups.

panelid(varname) specifies the panel identifier variable. This is used for
the within (fixed-effects) transformation via xtreg with the fe option.
The panel structure must be declared with xtset before running xtvfreg.

meanvars(varlist) lists the covariates to include in the mean (location)
equation. These variables predict the expected value of the dependent variable.

varvars(varlist) lists the covariates to include in the variance (scale)
equation. These variables model heteroscedasticity by predicting the variance of
the dependent variable. The variance model uses squared within-group residuals as
the dependent variable. varvars() may overlap with meanvars().

Options

tvar(varname) optionally specifies a time variable. Currently not used in
the estimation but may be used for future extensions.

converge(real) sets the convergence tolerance for the iterative algorithm.
Convergence is achieved when the absolute change in the summed log-likelihood of
the variance equation between iterations falls below this threshold. The default
is converge(1e-6).

maxiter(integer) sets the maximum number of iterations allowed before
stopping the algorithm. A warning is displayed if convergence is not achieved
within this limit. The default is maxiter(100).

nolog suppresses the display of the iteration log, which shows the
log-likelihood value and change at each iteration for each group.

table requests a comparison table of the mean equation estimates across
all groups using esttab (if installed). The table includes iteration
counts, convergence status, and final log-likelihood values.

combined displays two additional tables: (1) mean equation results for
all groups side-by-side, and (2) variance equation results for all groups
side-by-side. This option requires esttab to be installed
(ssc install estout). This provides an easy way to compare coefficients
across groups.

Remarks

xtvfreg uses an iterative weighted generalized least squares (GLS) approach:

1. Initial estimation: Fit the mean model with glm using
family(gaussian) and link(identity). Compute residuals.

2. Within transformation: Run xtreg, fe on the residuals
to extract within-group (fixed effects) residuals. Square these residuals to
obtain the dependent variable for the variance equation.

3. Variance estimation: Fit a variance model via glm with
family(gamma) and link(log) using the squared residuals. This
estimates the variance function S².

4. Weighted re-estimation: Re-estimate the mean model using analytic
weights [aw=1/S²], which accounts for heteroscedasticity.

5. Iteration: Repeat steps 2-4 until the change in the log-likelihood
of the variance equation is less than the convergence tolerance.

For each group, convergence information is displayed showing the number of
iterations and the initial and final log-likelihood values. The command also
reports a variance decomposition that partitions the total variance of the
dependent variable into three components:

1. Variance explained by mean model - The variance of fitted values
from the weighted mean equation. This represents systematic variation captured by
the mean predictors (covariates).

2. Variance explained by variance model - The mean of the estimated
variance function (S²). This represents the average level of heteroscedasticity
modeled by the variance equation predictors.

3. Unexplained variance - The remaining variance not accounted for
by the mean and variance models. This includes individual fixed effects and
idiosyncratic variation not captured by the models.

Each component is expressed both in absolute terms (variance units) and as a
percentage of total variance. These proportions help assess the relative
importance of the mean structure and heteroscedasticity in explaining variation
in the outcome.

Stored estimates: The command stores three sets of estimates for each group
(where [group] is the group identifier):

beta_[group] - Mean equation estimates with metadata (main results)

mean_[group] - Mean equation estimates

var_[group] - Variance equation estimates

These can be replayed with estimates replay or estimates table,
and can be used with esttab, etable, or the collect system.

Interpretation: Coefficients in the mean equation are interpreted as in
standard linear regression. Coefficients in the variance equation are on the log
scale (due to the log link): positive coefficients indicate that the variable
increases variance, while negative coefficients indicate that it decreases variance.
An effect of an X variable in the variance model on the Y scale of the mean model
can be interpreted as follows: A one-unit increase in X is associated with an exp(beta_x)
times change in the expected variance of the prediction errors (residuals) of the Y variable
in the mean model. This implies that the X variable is influencing the heteroscedasticity of
the mean model. A positive beta_x (i.e., exp(beta_x) > 1) suggests that as X increases,
the spread of the residuals around the predicted Y values tends to increase, while a negative
beta_x (i.e., exp(beta_x) < 1) suggests the spread tends to decrease. Put differently and
succinctly (in terms of inequality), an X variable in the variance model has a multiplicative
effect on within-group inequality whereas an X variable in the mean model has an additive
effect on between-group inequality.

Examples

Setup

. webuse nlswork, clear

Create within-group means and deviations

. egen mage = mean(age), by(idcode)

. egen mhours = mean(hours), by(idcode)

. egen mtenure = mean(tenure), by(idcode)

. gen dage = age - mage

. gen dhours = union - mhours

. gen dtenure = tenure - mtenure

. gen sampwgt = 1

Declare panel structure

. xtset idcode year

Basic estimation by region (south) with probability weights

. xtvfreg ln_wage, groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure)

With combined tables

. xtvfreg ln_wage, groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure) combined

Suppress iteration log

. xtvfreg ln_wage, groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure) nolog

Display comparison table across groups with sampling weights

. xtvfreg ln_wage [pweight=sampwgt], groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure) table

Display comparison table across groups with if selecion sampling weights

. xtvfreg ln_wage if race==1 [pweight=sampwgt], groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure) table

Replay stored estimates

. estimates replay beta_0

. estimates replay mean_1

. estimates replay var_0

Use with esttab

. esttab mean_*, se star(* 0.10 ** 0.05 *** 0.01)

. esttab var_*, se star(* 0.10 ** 0.05 *** 0.01)

Use with etable, which only output one set of the model results

. etable, replay stars(.05 * .01 ** .001 ***, prefix(Note:))

. etable, replay title(Table 2. Regression Estimates) export(RegResults.docx, replace)

Completely silent execution

. xtvfreg ln_wage [pweight=sampwgt] if race==1, groupvar(south) panelid(idcode) meanvars(collgrad mage mhours mtenure dage dhours dtenure) varvars(collgrad mage mhours mtenure dage dhours dtenure) table combined

Stored results

xtvfreg stores the following in r():

Scalars

r(ngroups) number of groups estimated

r(maxiter) maximum iterations allowed

r(converge) convergence criterion

r(group#_iter) iterations for group #

r(group#_converged) convergence status for group # (1=converged, 0=not)

r(group#_ll) final log-likelihood for group #

Macros

r(groups) list of group values

For each group, xtvfreg stores estimation results in e() under the names
beta_[group], mean_[group], and var_[group]. These contain standard
glm results plus the following additional items in beta_[group]:

Scalars

e(group) group identifier value

e(n_iter) number of iterations until convergence

e(vf_converged) convergence indicator (1=yes, 0=no)

e(ll_init) initial log-likelihood

e(ll_final) final log-likelihood

Macros

e(vf_groupvar) name of grouping variable

e(vf_groupval) value of this group

e(vf_cmd) "xtvfreg"

References

Mooi-Reci, I., and T. F. Liao. 2025. Unemployment: a hidden source of wage
inequality? European Sociological Review 41(3): 382-401.
https://doi.org/10.1093/esr/jcae052

Author

Tim F. Liao

University of Illinois Urbana-Champaign

tfliao@illinois.edu

Also see

Manual: [R] glm, [XT] xtreg

Online: glm, xtreg, xtset, estimates,
esttab (if installed), etable (if installed)