*! xtgfe version 1.5.5 July 2026 H. Ozan Eruygur

help for xtgfe

Title

xtgfe -- Grouped fixed-effects (GFE) estimation for panel data
(Bonhomme and Manresa, 2015, Econometrica)

Syntax

xtgfe depvar [indepvars] [if] [in], groups(#)
[options]

xtgfe plot [, title(string) means
twoway_options]

xtgfe fx [newvar]

Model
groups(#) number of groups G; with bic, the maximum
Gmax

tinvariant time-invariant group effects alpha(g) (default:
time-varying alpha(gt))

hetcoef(varlist|_all) group-specific coefficients for the
listed covariates (extension S4.2)

subgroups(numlist) two-layer specification alpha(gh,t) = a(gt) +
b(gh): one subgroup count per group (extension S4.1)

bic select the number of groups by BIC over 1..Gmax

refit with bic: re-search at the selected G and report
the better solution (not in the original codes)

Algorithm
algorithm(#) 1 = iterative (Algorithm 1); 2 = variable
neighborhood search (Algorithm 2, default)

randstarts(#) number of random starting values

neighbors(#) maximum neighborhood size in VNS

steps(#) number of VNS sweeps per start; default 128, as in
the gretl package

maxiter(#) maximum inner-loop iterations; default 1000

verbose print the objective attained at each start

Standard errors
vce(sandwich) large-N, large-T sandwich s.e., clustered by
unit (default)

vce(bootstrap) bootstrap s.e., unit resampling,
bias-corrected

vce(fixedt) Pollard (1982) large-N, fixed-T analytic
s.e.

reps(#) bootstrap replications; default 100

bstarts(#) random starts per bootstrap replication; default
32

epsilon(#) kernel bandwidth for vce(fixedt); default:
automatic Silverman-type rule

Reporting
generate(newvar) name of the group-assignment variable;
default gfe_group

longrun(varname) lagged dependent variable for the long-run
effects table (auto-detected by default; this option overrides)

showalpha display the estimated group effects alpha(gt)

showfreq additionally tabulate units per group (a compact
per-group count is always displayed)

The data must be xtset. Time-series operators (L. etc.) and
factor variables (i.var, expanded to 0/1 indicators internally,
base level dropped) are allowed among the covariates. In the default model
the group effects alpha(gt) already contain a full set of group-specific
time effects, so a regressor with no cross-sectional variation - time
dummies (i.timevar), or any aggregate time series - is
perfectly collinear and is refused with an error; with tinvariant
such regressors are allowed. If you restrict the sample with keep,
generate the lags before restricting so that their source rows are
not lost.

Description

xtgfe estimates linear panel-data models with a grouped structure
of unobserved heterogeneity, as proposed by Bonhomme and Manresa (2015). In
these models, units (countries, firms, individuals, regions, ...) are
assumed to belong to a small number of latent groups that share common time
patterns: the unobserved heterogeneity is structured into a finite number of
groups, say G, and units within the same group share a common time-varying
unobserved component. The baseline model is

y(it) = x(it)'theta + alpha(gi,t) + v(it), i = 1,...,N, t = 1,...,T, (1)

where y(it) is the outcome of unit i at time t, x(it) is a vector of
observed covariates, theta is the parameter vector of interest, and v(it) is an
idiosyncratic error. The distinctive element is alpha(gi,t): gi denotes
the latent group membership of unit i, so that alpha(gi,t) is a
group-specific, time-varying effect. This structure allows for rich
patterns of unobserved heterogeneity - e.g., group-specific trajectories
- while avoiding the curse of dimensionality of unrestricted unit-by-time
fixed effects: instead of N*T incidental parameters, only G*T group-time
effects are estimated. Group membership gi is not observed and does
not need to be specified by the researcher: it is estimated jointly with
theta and the group-time effects by minimizing the total sum of squared
residuals over all possible groupings.

A nested specification allows the group effects to be constant over time,

y(it) = x(it)'theta + alpha(gi) + v(it), (2)

that is, latent group-specific intercepts ("grouped intercepts" or clustered
fixed effects). This restricted version is requested with the
tinvariant option; comparing the fit of (1) and (2) indicates whether
the heterogeneity is genuinely time-varying.

This structure answers questions that standard fixed effects cannot: Which
units follow a common time pattern of unobservables (convergence clubs,
waves of democratization, common technology or policy regimes)? Who belongs
to which group, and what does each group's time profile look like? Is the
effect of x robust once time-varying grouped heterogeneity is allowed for?
How many groups does the data support (bic)? Do slopes differ across
latent groups (hetcoef())? Is there an additional layer of
within-group, time-invariant heterogeneity (subgroups())?

Unlike unit-by-time fixed effects (infeasible) or interactive fixed effects
(which requires large T), GFE remains informative in short panels because
the heterogeneity is restricted to G groups. Under suitable regularity
conditions, BM show that the GFE estimator is consistent as both the
cross-sectional dimension N and the time dimension T grow, with the number
of groups G held fixed; the large-T part of the framework is what guarantees
that misclassification of the group assignment becomes asymptotically
negligible (T may grow much more slowly than N). Compared with a priori
classifications (by region, income, etc.), the grouping is estimated from
the data so as to maximize the explained variation of the outcome.

Unbalanced panels are supported: cells with missing y or x are skipped
through the observation indicator D(it), exactly as in the authors' FORTRAN
code. Every unit needs at least one complete observation. Periods in which
no unit has a complete observation (e.g., an all-missing first period
created by lag operators) are dropped from the time grid automatically,
with a note. With time-varying effects, candidate groupings that leave a
(g,t) cell empty are discarded.

The command is a Stata/Mata port of the authors' Econometrica replication
codes (FORTRAN, Stata, MATLAB) and of the gretl GFE package by Lucchetti,
Pionati and Valentini. Every feature has been verified against published
numbers; see Replication of published results
below.

The algorithms

The GFE objective is non-convex because group membership is discrete: with
G groups and N units there are G^N possible assignments. xtgfe
implements the two heuristics proposed by BM (supplementary appendix S1).

Algorithm 1 (iterative). Starting from a random assignment, iterate two
steps until no unit switches group: (i) update: given the assignment,
estimate theta by pooled OLS on data demeaned within group(-time) cells, and
set alpha(gt) to the cell mean of y - x'theta; (ii) assignment: given
theta and alpha, reassign every unit to the group whose time profile fits
its residual path best (minimum SSR). This is a k-means-type descent: each
step weakly lowers the objective, so it converges to a local minimum. The
procedure is repeated from randstarts(#) random assignments and the
best solution is kept. Groups that become empty are refilled with the
worst-fitting units, as in the authors' FORTRAN code.

Algorithm 2 (variable neighborhood search, default). A local minimum of
Algorithm 1 is perturbed by randomly relocating n units to random groups
(n = 1, ..., neighbors(#)) and Algorithm 1 is re-run from the
perturbed assignment. If the objective improves, the new solution becomes
the incumbent and n resets to 1; otherwise n increases, widening the search.
Each of steps(#) sweeps repeats this loop, and the whole procedure is
repeated from randstarts(#) random starts. VNS is far more robust to
local minima: in replication R5 below, the default VNS search attains the
optimum that BM report from 1,000,000 starts of Algorithm 1. BM produced
Table S.XI with Algorithm 2 and the light setting (5;10;5); the gretl
package hard-codes 128 sweeps per start; xtgfe defaults to the gretl
depth and leaves all three parameters user-settable.

Because the problem is non-convex, always set seed for
reproducibility, and inspect verbose/e(objs): if many starts
reach the same minimum, the solution is numerically reliable (this mirrors
the authors' outputobj.txt diagnostic). If the best value is attained only
rarely, increase randstarts() and steps().

Choosing the number of groups

Following BM, the number of groups can be selected by minimizing the
following Bayesian information criterion, subject to an assumed maximum
value Gmax (request it with bic, where groups(#) then plays the
role of Gmax):

BIC(G) = SSR(G)/NT + sigma2*(G*T + N + K)/NT*ln(NT),

where SSR(G) is the minimized sum of squared residuals with G groups, K is
the number of regressors, and sigma2 is a consistent estimator of Var(v(it)).
Following the authors, sigma2 is computed from the largest model:

sigma2 = SSR(Gmax) / (NT - Gmax*T - N - K).

The penalty counts all estimated parameters: G*T group-time effects, N group
memberships, and K coefficients (with tinvariant, G group intercepts
replace the G*T term; in unbalanced panels NT is the number of complete
cells). xtgfe evaluates every G from Gmax down to 1 (G = 1 is pooled
OLS with time effects), reports the full table, stores it in e(bic),
and reports the model found for the minimizing G - exactly as in BM's
original pipeline and in the gretl package, where the selected G's estimates
come from that G's own search during the grid. Since the search is
stochastic, the grid fit at the selected G can occasionally be a local
minimum; the refit option (an xtgfe addition, not present in the
original codes) runs one extra full search at the selected G and reports the
better of the two solutions. BM show that, when T grows more
slowly than N, this criterion yields an upper bound on the true number of
groups - in the income-democracy application it selects G = 10 (Table
S.XI).

The empirical example used throughout

All examples use the income-and-democracy application of Bonhomme and
Manresa (2015, Section 4), based on the five-year panel of Acemoglu,
Johnson, Robinson and Yared (2008). The estimated equation is the dynamic
panel model of BM, equation (22):

democracy(it) = theta1*democracy(it-1) + theta2*log(GDPpc)(it-1) + alpha(gi,t) + v(it)

that is, Acemoglu et al.'s income-democracy regression in which the country
and year fixed effects are replaced by grouped fixed effects: countries
belong to G latent groups, each with its own time path of democracy
(stable-high, stable-low, early transition, late transition, ...).

The examples use Acemoglu_etal.dta: the ready-made estimation sample
distributed with the gretl GFE package, converted to Stata format, so that
Stata and gretl users work with the same file. It is a balanced panel
of 90 countries and 7 five-year periods (1970-2000), already xtset,
with the lags included as variables: fhpolrigaug is the Freedom House
political-rights index normalized to [0,1] (the democracy measure and
dependent variable); lag_dem is its five-year lag; lag_income
is the five-year lag of log real GDP per capita (Penn World Table);
code, ccode and country identify countries, year
the period. Setting up any example is therefore just:

. use https://eruygurakademi.com/datasets/xtgfe/Acemoglu_etal.dta, clear

. set seed 8273647

(set seed makes the stochastic group search reproducible and is
always recommended; any number will do.) The gretl version of the data,
Acemoglu_etal.gdt, ships with the GFE package; it is also mirrored,
together with the Stata file, the gretl example script
BonMan_replication.inp and the raw data, at
https://eruygurakademi.com/datasets/xtgfe/.

How this dataset was built from the raw data - instructive if you
need to prepare a sample of your own. Starting from the raw five-year panel
5yearpanel.dta (same address):

. use https://eruygurakademi.com/datasets/xtgfe/5yearpanel.dta, clear

. xtset code_numeric year, delta(5)

. gen lag_dem = L.fhpolrigaug

. gen lag_income = L.lrgdpch

. gen byte okobs = !missing(fhpolrigaug, lag_dem, lag_income) & inrange(year,1970,2000)

. bys code_numeric: egen nok = total(okobs)

. keep if inrange(year,1970,2000) & nok==7 & samplebalancefe==1

xtset ..., delta(5) declares that one time step is 5 calendar years,
so that L. shifts by one five-year period. The two gen lines
create the regressors of the model - a specification choice (the
model is a dynamic panel), not data cleaning; generate lags before any
keep so that their source rows are not lost. The
okobs/nok/keep lines reproduce exactly the authors'
90-country balanced sample (samplebalancefe is the authors' own flag
and exists only in this dataset).

With your own data none of this surgery is required - the minimal usage
is just:

. use mydata, clear

. xtset id year

. set seed 12345

. xtgfe y x1 x2, groups(4)

Unbalanced panels and missing cells are handled automatically (units with no
complete observation at all must be dropped; the command says so if it finds
any). A balanced panel is required only for vce(fixedt) and
subgroups(); in that case balance with:

. gen byte okobs = !missing(y, x1, x2)

. bys id: egen nok = total(okobs)

. su nok, meanonly

. keep if nok == r(max)

Options with examples

All examples below assume the replication sample above has been
prepared.

groups(#) sets the number of groups G (required). With bic it is
the maximum number Gmax over which BIC searches.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4)

Estimates 4 latent groups. Interpretation: theta is the effect of the
covariates net of any heterogeneity following one of 4 common time paths;
the paths are in e(alpha) and the memberships in
gfe_group.

tinvariant restricts group effects to be constant over time
(alpha(g)).

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) tinvariant

Interpretation: groups now differ only in level, like G "cluster dummies".
Compare its SSR with the time-varying fit: a large gap indicates that the
heterogeneity is genuinely time-varying.

algorithm(#), randstarts(#), neighbors(#), steps(#)
and maxiter(#) control the optimizer. Defaults: algorithm 2 with
floor(8*sqrt(G)) starts, floor(sqrt(N)) neighbors and 128 VNS sweeps per
start - the search depth hard-coded in the gretl package; algorithm 1
with 1024 starts (4096 when G >= 8). For reference, BM produced Table S.XI
with the much lighter setting (5 starts, 10 neighbors, 5 sweeps). Progress
dots stream while the search runs, one per random start; during bic
the percentage of the G grid completed is interleaved with the dots, and
during vce(bootstrap) one dot is shown per 10 replications.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10)

More starts and sweeps = a more reliable global minimum at a longer run
time. Interpretation: if increasing them no longer lowers the SSR, the
reported solution is (numerically) the optimum.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) algorithm(1) randstarts(2048)

Algorithm 1 is faster per start but more easily trapped; both BM and the
gretl manual show it can stop at a slightly higher SSR than Algorithm
2.

verbose prints the objective attained at each random start (also
stored in e(objs)); the counterpart of the authors' outputobj.txt
stability check.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) verbose

Interpretation: the share of starts reaching the reported minimum measures
how trustworthy the solution is; a minimum found only once in many starts
calls for more searching.

vce(sandwich) (default) computes the large-N, large-T clustered
sandwich s.e. of BM (S3): pooled OLS of y on x and group(-time) dummies with
clustering at the unit level, conditional on the estimated grouping (same
method as the gretl package).

vce(bootstrap), with reps(#) and bstarts(#), re-estimates
the full model on samples of units drawn with replacement and adds the
squared bootstrap bias, as in BM. Per-replication coefficients are stored in
e(bootreps) (the authors' replications.txt).

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) vce(bootstrap) reps(100)

Interpretation: bootstrap s.e. are BM's most conservative choice; in Table
S.XI they are 2-3 times larger than the sandwich s.e. because they also
reflect uncertainty in the estimated group assignment.

vce(fixedt), optionally with epsilon(#), computes Pollard
(1982)-type large-N, fixed-T analytic s.e. (BM section S2.2, a port of
the authors' fixedT_function.m). It corrects the sandwich formula with
kernel-weighted "frontier" terms accounting for units close to switching
groups. The bandwidth defaults to the authors' Silverman-type rule and is
reported and stored in e(bandwidth). Requires a balanced panel,
time-varying effects and covariates.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) vce(fixedt)

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) vce(fixedt) epsilon(0.10)

Interpretation: fixed-T s.e. lie between the sandwich and the bootstrap
(Table S.XI, G=10: .049 < .062 < .124 for lagged democracy); they are the
theoretically preferred choice when T is short. Report sensitivity to
epsilon() as BM do in their appendix.

Which vce() to use. The three estimators differ in how much of the
uncertainty in the estimated group assignment they take into account.
vce(sandwich) conditions on the estimated grouping: it is justified by
large-N, large-T asymptotics, where misclassification vanishes; it is
the fastest, but it understates uncertainty when T is short.
vce(fixedt) keeps T fixed in the asymptotics and adds kernel-weighted
"frontier" terms for units close to the boundary between two groups, i.e.,
units that could plausibly have been assigned elsewhere; it is the
theoretically preferred choice in short panels, at the cost of requiring a
balanced panel and a bandwidth choice. vce(bootstrap) re-estimates
everything - including the grouping - on each resample of units, so
it captures the full sampling uncertainty; it is the most conservative (BM's
preferred cautious choice) and the slowest. The typical ordering is
sandwich < fixed-T < bootstrap: in Table S.XI at G = 10 the s.e. of lagged
democracy are .049 < .062 < .124.

Practical guidance: use vce(sandwich) while exploring specifications
(it is instantaneous); base final inference on vce(fixedt) when T is
short (as in most applications; T = 7 here); for referee-proof results,
report all three as BM do in Table S.XI - run the command three times
with the same seed, the coefficients are identical and only the s.e. column
changes. In unbalanced panels vce(fixedt) is unavailable; use
vce(bootstrap), as BM do. With hetcoef() or subgroups()
only vce(sandwich) is currently available. Finally, the gap between
sandwich and bootstrap s.e. is itself a diagnostic: a large gap signals that
the groups are not sharply separated, so assignment uncertainty is
substantial - take the bootstrap seriously and consider a smaller G.

bic selects the number of groups by minimizing the BIC of BM (S20)
over G = 1, ..., Gmax, using the Gmax model to estimate the error variance.
The full table is displayed and stored in e(bic).

. xtgfe fhpolrigaug lag_dem lag_income, groups(15) bic

Interpretation: the starred row minimizes BIC; BM show that this G is an
upper bound for the true number of groups. In the application BIC selects
G=10 (Table S.XI).

hetcoef(varlist|_all) makes the coefficients of the listed covariates
group-specific: y(it) = x(it)'theta(gi) + alpha(gi,t) + v(it) (BM extension
S4.2). Covariates not listed keep a common coefficient. Results are posted
as one equation per group (plus a Common equation), so postestimation
commands work per group. Only vce(sandwich); not with bic.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) hetcoef(lag_income)

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) hetcoef(_all)

. nlcom _b[Group1:lag_income]/(1-_b[Group1:lag_dem])

Interpretation: tests whether the effect of income differs across latent
groups; in BM Table S16 the income coefficient ranges from .04 (low
democracy) to .12 (early transition) once both slopes are heterogeneous.
The nlcom line computes the group-specific cumulative (long-run)
income effect.

subgroups(numlist) estimates the hierarchical two-layer model
alpha(gh,t) = a(gt) + b(gh) (BM extension S4.1): G primary groups
with time-varying paths, each split into the given number of time-invariant
subgroups. The primary assignment is stored in gfe_group, the subgroup
in gfe_group_sub. Requires a balanced panel and time-varying effects;
only vce(sandwich); not with bic.

. xtgfe fhpolrigaug lag_dem lag_income, groups(3) subgroups(5 2 2) showfreq

Interpretation: BM's Table S13/Figure S6 specification: 3 dynamic patterns
(stable / early transition / late transition) with 5, 2 and 2 level shifts
within them (high ... low democracy). Use it when units share a common
dynamic but differ in levels.

generate(newvar) names the assignment variable (default
gfe_group, silently replaced when it exists). A compact units-per-group
count is always part of the output (as in gretl's gfe_printout);
showfreq additionally shows a full tabulation.

Long-run effects. When one of the covariates is the lag of the
dependent variable (a dynamic model), xtgfe detects it automatically
- by matching its values against the within-panel one-period lag of the
dependent variable - and displays, below the coefficient table, the
long-run (cumulative) effects b_k/(1 - b[lagdep]) of every other covariate
with delta-method standard errors. Use longrun(varname) to point to
the lagged dependent variable explicitly if detection is not possible
(e.g., the stored lag differs numerically). This reproduces the Cum.Income
computation in gretl's BonMan_replication.inp; the same numbers can also be
obtained with nlcom. In static models no table is shown.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10)

Interpretation: with lag_dem = .2772 and lag_income = .0753, the long-run
income effect is .0753/(1-.2772) = .1041 (.0088) - the Cum.Income
value of BM Figure 1 and Table S.XI.

showalpha prints the estimated group effects: the T x G matrix
alpha(gt) with periods in rows and groups in columns (one column with
tinvariant). The same matrix is stored in e(alpha) and is used
by xtgfe plot and xtgfe fx.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) showalpha

Interpretation: each column is one group's estimated time path of
unobserved heterogeneity; reading down a column shows how that group's
level of democracy (net of covariates) evolves over 1970-2000.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) generate(club) showfreq

Interpretation: club identifies each country's estimated group; use it
for listings (tab country if club==1), maps or follow-up
regressions.

Postestimation subcommands

xtgfe plot graphs the estimated group effects from the last
estimation (the counterpart of gretl's group_plot). Time-varying
model: one line per group over the sample periods; tinvariant: a bar
chart. With means it instead plots the group-specific means of the
dependent variable (BM Figure 2 style). All twoway_options are passed
through.

. xtgfe plot, title("Group trajectories") xlabel(1970(5)2000)

. xtgfe plot, means

Interpretation: the alpha(gt) lines are the estimated common paths of
unobserved heterogeneity; the means version shows the raw outcome
paths by group, which is how BM present Figure 2.

xtgfe fx [newvar] generates a variable with the estimated group
effect alpha(gi,t) of every observation (the counterpart of gretl's
group_fx; default name gfe_fx).

. xtgfe fx

. predict double xb0, xb

. gen double fitted = xb0 + gfe_fx

. gen double resid = fhpolrigaug - fitted

Interpretation: gfe_fx is the estimated unobserved-heterogeneity
component of each observation; combined with x'theta it yields fitted values
and residuals.

Replication of published results

Each block below reproduces a published number, so that users can verify
that xtgfe delivers the same values as the original software. Every
block starts from the data load in
The empirical example used throughout
(Acemoglu_etal.dta, 90 countries, 7 periods); all files are available
at https://eruygurakademi.com/datasets/xtgfe/.

R1. Baseline GFE, G = 10 - BM Table S.XI / gretl manual, section 3.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) showfreq

Expected: lag_dem = .2772 (s.e. .0488), lag_income = .0753
(s.e. .0080), SSR = 7.74906 - identical, to all printed
digits, to Table S.XI (row G = 10, first s.e. per column) and to the gretl
GFE manual.

In gretl: include GFE.gfn, then
open Acemoglu_etal.gdt --quiet --frompkg=GFE,
list X = lag_dem lag_income,
mod = gfe_estimate(fhpolrigaug, X, 10), gfe_printout(mod, 1).

Original codes: Econometrica supplementary zip (Bonhomme_Manresa_codes),
folder Application: GFE_replication_code.do with Replic = 1 (calls the
authors' FORTRAN executable), then GFE_estimates.m reproduces Table S.XI and
Figures 1-2 in MATLAB.

R2. Pollard fixed-T s.e. - BM Table S.XI, second s.e. per column.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) vce(fixedt)

Expected: bandwidth = .0777; s.e. = .0623 (lag_dem) and
.0099 (lag_income), matching Table S.XI's (.062, .010).

In MATLAB: fixedT_function.m called from GFE_estimates.m (epsilon grid
0.05-0.15 with the Silverman-rule pick).

R3. Bootstrap s.e. - BM Table S.XI, third s.e. per column.

. xtgfe fhpolrigaug lag_dem lag_income, groups(10) vce(bootstrap) reps(100)

Expected: s.e. of the order (.12, .015), as in Table S.XI; the exact value
is seed-dependent by the nature of the bootstrap.

Original codes: Bootstrap_version.exe via GFE_replication_code.do.

R4. BIC choice of G and cross-software check - BM Table S.XI / gretl's BonMan_replication.inp.

. xtgfe fhpolrigaug lag_dem lag_income, groups(15) bic

. nlcom _b[lag_income]/(1-_b[lag_dem])

Expected (the full grid takes a few minutes): BIC is minimized at
G* = 10 (starred row: BIC .0341, SSR
7.7491); the selected model reports lag_dem = .2772 (.0488) and
lag_income = .0753 (.0080); the cumulative income effect from
nlcom is .1041 (.0088). This is the Stata counterpart of the
gretl GFE package's own example script BonMan_replication.inp
(shipped with the package, mirrored at the address above), which runs the
identical exercise - gfe_estimate(fhpolrigaug, X, 15) with
BICselect=1 - and returns G* = 10, obj = 7.74906 and Cum.Income =
0.104117 (0.0088), i.e., the same values. Seeds are software-specific
(different RNGs), but both programs converge to the same optimum; if a run
stops slightly above SSR 7.749, increase randstarts()/steps()
(or, in xtgfe, add the refit option).

R5. Heterogeneous coefficients - BM Table S16.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) hetcoef(lag_income)

Expected (top panel of Table S16): common lag_dem = .288 (.056);
group-specific lag_income = (.103, .047, .087, .082) up to group
relabeling; SSR = 14.179.

. xtgfe fhpolrigaug lag_dem lag_income, groups(4) hetcoef(_all)

Expected (bottom panel of Table S16, up to relabeling): (lag_dem, lag_income)
pairs (.644, .070) (.319, .041) (.016, .122) (.248, .090) with s.e.
(.077, .019) (.113, .014) (.081, .022) (.097, .018); SSR = 13.540. BM
obtained this with 1,000,000 starts of Algorithm 1; 24 VNS starts
suffice.

In MATLAB: Heterogeneous_coefficientsA.m / Heterogeneous_coefficientsB.m
in the Application folder of the supplementary zip.

R6. Two-layer specification - BM Table S13 / Figure S6.

. xtgfe fhpolrigaug lag_dem lag_income, groups(3) subgroups(5 2 2) showfreq

. xtgfe plot, xlabel(1970(5)2000)

Expected: SSR = 11.702; primary group sizes (64, 13, 13) =
"Stable", "Early transition", "Late transition" in Table S13's two-layer
column; the plot reproduces the 9 fine trajectories of Figure S6.

In MATLAB: GFE_twolayers_computation.m /
GFE_twolayers_estimates.m.

Stored results

xtgfe stores the following in e() (with covariates):

e(b), e(V) coefficients and VCV (one equation per group
with hetcoef())

e(alpha) group effects: T x G (time-varying), G x 1
(time-invariant), or T x S fine trajectories (two-layer)

e(ssr), e(ll) minimized SSR and Gaussian
log-likelihood

e(G), e(N_units), e(T) number of groups and panel
dimensions

e(algorithm) algorithm actually used (1 or 2)

e(randstarts), e(neighbors), e(steps) search settings actually used

e(objs) objective attained at each random start (not with
bic)

e(etime) elapsed estimation time, in seconds

e(bic) BIC table (G, BIC, SSR), with bic

e(bandwidth) kernel bandwidth, with vce(fixedt)

e(bootreps) per-replication coefficients, with
vce(bootstrap)

e(Kc), e(hetvars) with hetcoef(): number of common
coefficients; list of group-specific covariates

e(S), e(H) with subgroups(): total fine-group count; subgroup counts per group

e(a_primary), e(b_sub) with subgroups(): effect components a(gt) and b(gh)

e(subgroupvar) with subgroups(): subgroup variable name

e(tvals) time values of the estimation window

e(timevar), e(panelvar), e(groupvar) identifier variable names

The estimated group of each unit is stored in the variable given by
generate() (gfe_group by default; plus gfe_group_sub with
subgroups()). Without covariates, group effects are saved in the
global matrix xtgfe_alpha.

References

Acemoglu, D., S. Johnson, J. A. Robinson, and P. Yared (2008). Income and
democracy. American Economic Review 98(3): 808-842.

Bonhomme, S. and E. Manresa (2015). Grouped patterns of heterogeneity in
panel data. Econometrica 83(3): 1147-1184; Supplementary Appendix and
replication codes.

Lucchetti, R., A. Pionati and F. Valentini (2026). Grouped Fixed Effects
estimators in gretl: the GFE package, version 0.1.

Pollard, D. (1982). A central limit theorem for k-means clustering.
Annals of Probability 10(4): 919-926.

Author

H. Ozan Eruygur

AHBV University, Ankara, Turkiye.

Department of Economics

https://www.ozaneruygur.com

eruygur@gmail.com

Eruygur Academy and Consulting (Eruygur Akademi ve Danismanlik), Ankara,
Turkiye.

https://www.eruygurakademi.com

eruygurakademi@gmail.com

xtgfe v1.5.5 - July 2026

The estimator implemented here was proposed by Stephane Bonhomme (University
of Chicago) and Elena Manresa in Bonhomme and Manresa (2015). xtgfe is
a Stata/Mata port of the authors' Econometrica replication codes (FORTRAN,
Stata and MATLAB, including fixedT_function.m and the extension codes) and
of the gretl GFE package by Riccardo (Jack) Lucchetti, Alessandro Pionati
and Francesco Valentini. All results were verified against the published
values in the paper's supplementary appendix (Tables S.XI, S13, S16) and in
the gretl package documentation.

Please cite as:

Eruygur, H. O. 2026. xtgfe: Grouped fixed effects estimation for panel
data (Bonhomme and Manresa, 2015). Stata package version 1.5.5. Available
from: https://www.eruygurakademi.com.