Skip to content

Repository files navigation

xhdfe

Linear regression with multiple high-dimensional fixed effects — in Stata, Python and R, on one fast C++ core.

Version 2.24.1 · License: MIT · Stata + Python + R · Optional CUDA GPU


What is xhdfe?

xhdfe estimates linear models with any number of high-dimensional fixed effects (HDFE) — the worker–firm, patent–inventor, and multi-way panel designs common in applied economics. It mirrors the defaults and reporting of reghdfe (Correia 2016): under the default reghdfe-comparable tolerance mode, coefficients match reghdfe at the same nominal tolerance. The same estimator is exposed through three front-ends — a Stata command, a Python package, and an R package — all sitting on a single compiled C++ core. CPU is the reference backend; an optional CUDA GPU absorber is available for large problems.

The package also ships xfe (hence the repository name xhdfe-xfe), a companion Stata command that partials out — residualizes — variables against multiple high-dimensional fixed effects on the same core, without fitting a regression. See Stata below and help xfe.

As an illustration, the table below reports median estimator-call runtimes for an AKM-style wage regression using Portuguese matched employer-employee data. The specification uses 55,947,171 observations and absorbs 5,948,793 worker, 799,265 firm, and 36 year fixed effects. It includes common seniority controls and clusters standard errors at the worker level:

Implementation Backend Seconds Speedup vs. reghdfe
reghdfe, Stata CPU 3,667.5 1.0x
FixedEffectModels.jl CPU 916.3 4.0x
fixest CPU 486.5 7.5x
pyfixest CPU 110.4 33.2x
FixedEffectModels.jl CUDA 105.7 34.7x
xhdfe, Stata CPU 61.3 59.8x
xhdfe, Python CPU 53.6 68.4x
xhdfe, Stata CUDA 22.7 161.7x
xhdfe, Python CUDA 14.5 252.2x

The xhdfe rows use the speed-oriented xhdfe-fast mode; the default reghdfe-comparable mode is somewhat slower but matches reghdfe more tightly.

Features

  • Multiway HDFE — any number of absorbed fixed-effect dimensions, plus two-way categorical interactions.
  • Dual Python API — low-overhead arrays or an optional R-style formula frontend with categories and interactions.
  • Publication tables — fitted Python results plug directly into maketables.ETable without an adapter or runtime dependency.
  • Heterogeneous (group-specific) slopesfe#c.x and fe##c.x designs.
  • IV / 2SLS with absorbed fixed effects.
  • Weights — analytic, frequency, probability, and importance weights.
  • Robust and multiway-cluster standard errors.
  • DoF adjustments — reghdfe-style singleton dropping and degrees-of-freedom logic, plus fixest-style small-sample corrections (ssc).
  • Fixed-effect recoverysavefe / savefes (Stata), fixef() (R), retain_fes (Python).
  • Group-level outcomes with individual fixed effects — the group() / individual() machinery.
  • Mobility groups and connected-component diagnostics.
  • Optional GPU — CUDA absorber with explicit request and status reporting; fail-closed (never a silent CPU fallback).
  • AKM / worker-firm post-estimation — leave-out (KSS) variance decomposition with plug-in, AGSU and KSS corrections, exact and Johnson-Lindenstrauss leverages, component standard errors, Andrews-Mikusheva weak-identification confidence intervals, fweights, and a leave-one-out connected-set utility (xhdfeakm / xhdfeconnected in Stata, xhdfe.akm in Python, xhdfe_akm_kss() in R); validated against Saggio's LeaveOutTwoWay (the canonical KSS implementation) and pytwoway. See docs/akm-kss.md.
  • Gelbach decompositionxhdfegelbach / xhdfe.gelbach / xhdfe_gelbach(), validated against Gelbach's b1x2 on overlapping classic OLS specifications, with multiple focal coefficients, multiple observed blocks, common and added HDFEs, and explicitly declared absorbed targets. Version 1.6.0 includes retained-sample provenance, connectivity and regularity diagnostics, joint-covariance inference, full-refit pairs bootstrap, and table and plot helpers. See docs/releases/RELEASE_NOTES_2.23.0.20260806.md.

Choose your language

The three packages call the same C++ estimator, so results agree across languages. Pick your front-end below. For GPU (CUDA) acceleration in any of them, see the GPU (CUDA) guide — it walks through installing with the GPU feature, requesting it, and verifying it in Stata, Python, and R.

Stata

One command installs everything. net install xhdfe installs the estimator and every companion command — xfe, xhdfeakm, xhdfeconnected, xhdfegelbach, xhdfegelbachbootstrap, xhdfegelbachetable, xhdfegelbachcoefplot, and xhdfegpu — together with the CPU plugin for your OS:

net install xhdfe, from("https://raw.githubusercontent.com/reisportela/xhdfe-xfe/gh-pages/stata") replace

That is all most users need. The commands you get:

Command What it does
xhdfe HDFE linear regression — the estimator (help xhdfe).
xfe Partials out / residualizes variables against the fixed effects, no regression (help xfe).
xhdfeakm Worker-firm (AKM) leave-out (KSS) variance decomposition (help xhdfeakm).
xhdfeconnected Largest leave-one-out connected set — KSS sample prep (help xhdfeconnected).
xhdfegelbach Gelbach (2016) decomposition of coefficient movements (help xhdfegelbach).
xhdfegelbachbootstrap Full-refit iid- or cluster-pairs bootstrap for Gelbach results (help xhdfegelbachbootstrap).
xhdfegelbachetable Publication-oriented Gelbach tables (help xhdfegelbachetable).
xhdfegelbachcoefplot Identity-preserving Gelbach waterfall plot (help xhdfegelbachcoefplot).
xhdfegpu Builds and installs a CUDA GPU plugin for this machine (help xhdfegpu).

If you want only the standalone xfe partial-out tool, you can install it by itself with net install xfe, from("…") replace. The online package uses Stata platform-specific g lines for Linux, macOS Apple Silicon/Intel, and Windows when a Windows plugin artifact exists.

Turn on the GPU (NVIDIA/CUDA) — one command

The online net-install site provides the CPU plugin. Certified releases may also publish separate Linux CUDA plugin assets on the Releases page. On a Linux machine with an NVIDIA GPU, the most direct way to build for that machine is to run the companion command once, right after net install:

xhdfegpu

xhdfegpu detects the GPU, compiles a plugin for its exact architecture, and installs it over the CPU plugin in place — same xhdfe.plugin / xfe.plugin, no renaming, no extra files. Then reload the plugin and request the GPU as usual:

discard
xhdfe price weight length, absorb(rep78) gpubackend(cuda)
display e(gpu_used)          // 1

On a machine without internet access, download the self-contained source zip (xhdfe-src.zip, attached to each release and served from the net-install site) on another machine, copy it over, and hand it to xhdfegpu:

xhdfegpu, zip("/path/to/xhdfe-src.zip")

xhdfegpu needs the NVIDIA CUDA toolkit (nvcc) and a C++ compiler; see help xhdfegpu. The zip is self-contained: Eigen, pybind11, the official version-pinned Rcpp source archive, and Stata's plugin inputs are vendored, so the package-side build needs no further downloads.

Install from a release ZIP (offline, no GitHub)

Download the distribution ZIP from the Releases page, unzip it, and point net install at the folder that contains xhdfe.pkg and stata.toc (this also installs xfe and the companions):

net install xhdfe, from("/path/to/unzipped/xhdfe/stata") replace

Build the plugin by hand (advanced)

xhdfegpu automates the GPU build; to do it yourself, get the source (clone the repo, or download xhdfe-src.zip) and build, then add the folder to adopath:

git clone https://github.com/reisportela/xhdfe-xfe.git
cd xhdfe-xfe
# CPU build (Linux + GCC; OpenMP recommended)
bash stata/tools/build-plugin.sh     --linux --openmp     # produces stata/xhdfe.plugin
bash stata/tools/build-xfe-plugin.sh --linux --openmp     # produces stata/xfe.plugin
# GPU build (Linux + NVIDIA; auto-detects the local architecture)
bash stata/tools/build-plugin.sh     --linux --openmp --cuda auto
bash stata/tools/build-xfe-plugin.sh --linux --openmp --cuda auto

For an explicit target use --cuda 90; for a shareable multi-GPU binary, --cuda-archs "75,80,86,89,90". See stata/BUILD_CUDA.md. Then adopath + "/path/to/xhdfe/stata".

Minimal example (public data shipped with Stata):

sysuse auto, clear
xhdfe price weight length, absorb(rep78)
xhdfe price weight length, absorb(rep78) vce(cluster rep78)

webuse nlswork, clear
xhdfe ln_wage grade age ttl_exp tenure not_smsa south, absorb(idcode year)
xhdfe ln_wage grade age ttl_exp tenure not_smsa south, absorb(idcode year occ_code)

* GPU (after xhdfegpu, or a CUDA-enabled plugin): request CUDA and verify
xhdfe ln_wage grade age ttl_exp tenure, absorb(idcode year) gpubackend(cuda)
display e(gpu_used)                 // must be 1
display "`e(gpu_backend)'"          // must be "cuda"

Python

Install from the repository. Python source builds require CMake, a C++ compiler, and the Python development headers for the Python you are using (Python.h). On Linux, install the matching system package first, for example python3-dev on Debian/Ubuntu or python3-devel on Fedora/RHEL/Rocky. On clusters without sudo, use a conda/mamba environment or a Python module that includes development headers.

python -m pip install "git+https://github.com/reisportela/xhdfe-xfe.git"
# or, from a clone:
git clone https://github.com/reisportela/xhdfe-xfe.git && cd xhdfe-xfe && python -m pip install .

With the GPU (CUDA) feature (Linux + NVIDIA only; needs the CUDA toolkit nvcc and always builds from source — never a prebuilt wheel). Set XHDFE_ENABLE_CUDA=auto: the build detects your GPU with nvidia-smi (the same check Stata's xhdfegpu uses) and compiles for that exact architecture. If no GPU or nvidia-smi is found it stops with a clear error — it never silently builds CPU-only when you asked for CUDA (CPU stays the default, plain pip install .).

# from a clone:
XHDFE_ENABLE_CUDA=auto python -m pip install .
# or straight from GitHub:
XHDFE_ENABLE_CUDA=auto python -m pip install "git+https://github.com/reisportela/xhdfe-xfe.git"

For an explicit target, set XHDFE_CUDA_ARCH=90 or CMAKE_CUDA_ARCHITECTURES=90. At runtime request the GPU with os.environ["XHDFE_GPU_BACKEND"] = "cuda" (see the example below) and confirm with reg.gpu_used_ == 1.

Minimal example:

import os
import numpy as np
import xhdfe

n = 2000
rng = np.random.default_rng(0)
y = rng.normal(size=n)
X = rng.normal(size=(n, 3))
firm_id = rng.integers(0, 200, size=n)
year_id = rng.integers(0, 20, size=n)

reg = xhdfe.HdfeRegressor(se_type="robust", tol=1e-8)
reg.fit(y, X, fes=[firm_id, year_id])

print(reg.coef_)
print(reg.summary())

# Optional: request CUDA after installing a CUDA-enabled build
os.environ["XHDFE_GPU_BACKEND"] = "cuda"
reg_gpu = xhdfe.HdfeRegressor(se_type="robust", tol=1e-8)
reg_gpu.fit(y, X, fes=[firm_id, year_id])
assert reg_gpu.gpu_used_ == 1
assert reg_gpu.gpu_status_code_ == 1
os.environ.pop("XHDFE_GPU_BACKEND", None)

On Windows, a GNU/MinGW build recursively bundles every detected non-system DLL dependency beside the extension. The package registers that internal directory before loading the native module and retains the Windows DLL-directory handle, so an installed wheel does not depend on the build toolchain remaining on PATH and does not require a user-side os.add_dll_directory(...) call. The build fails closed if the active toolchain cannot supply a matching x86-64 binary for any detected dependency. Machine-specific instruction tuning is disabled by default on Windows, so source-built artefacts do not inherit the build host's instruction set; explicitly local-only builds may opt in. The prebuilt Windows asset in this release is for CPython 3.12 x86-64; other Python ABIs require a source build and were not separately Windows-certified for this release.

The optional R-style formula frontend uses the same native estimator while adding named dataframe designs. Install the extra from a source checkout:

python -m pip install '.[formula]'

If xhdfe is already installed from a GitHub release asset, install its optional formula dependency with python -m pip install 'formulaic>=1.2.1,<2' 'pandas>=1.3'.

model = xhdfe.feols(
    "y ~ x1 + x2 + C(industry) | firm + year",
    data=d,
    se_type="cluster",
    clusters="firm",
)
print(model.tidy())

C(g) is the R-style counterpart of Stata's i.g; x:z is a product-only interaction and x*z expands to x + z + x:z. Fixed effects after | are read as identifier columns, encoded as group IDs, and passed to the native absorber, so they do not become dummy columns. A third part requests 2SLS with the same spelling as the R frontend, its left side naming the endogenous regressors and its right side the excluded instruments:

model = xhdfe.feols("y ~ x1 | firm + year | d ~ z1 + z2", data=d)

The existing HdfeRegressor.fit(y, X, ...) API remains the lowest-overhead route for small regressions in loops. See the packaged Python help for formula semantics, categorical reference levels, and prepare_formula().

Fitted results implement the duck-typed plug-in format of maketables, so publication tables need no adapter or registration step:

import maketables as mt

print(mt.ETable([model_a, model_b], drop="Intercept").make(type="tex"))

maketables is not an xhdfe dependency. Absorbed fixed effects become indicator rows, singleton counts and absorbed degrees of freedom are available as table statistics, and Stata variable labels carried on the estimation frame are picked up automatically. See the packaged Python help for the full statistic list.

R

Install from GitHub (the package lives in the r/xhdfe subdirectory). This gives you the CPU build:

# install.packages("remotes")
remotes::install_github("reisportela/xhdfe-xfe", subdir = "r/xhdfe")

With the GPU (CUDA) feature (Linux + NVIDIA only; needs the CUDA toolkit nvcc and always builds from source). Set XHDFE_ENABLE_CUDA=auto: the build detects your GPU with nvidia-smi (the same check Stata's xhdfegpu uses) and compiles for that exact architecture, failing with a clear error if no GPU or nvidia-smi is found rather than silently building CPU-only (CPU is the default install_github):

Sys.setenv(XHDFE_ENABLE_CUDA = "auto")
remotes::install_github("reisportela/xhdfe-xfe", subdir = "r/xhdfe")

or, from a clone: XHDFE_ENABLE_CUDA=auto R CMD INSTALL r/xhdfe. For an explicit target, set XHDFE_CUDA_ARCH=90. GPU use is then per call via backend = "cuda" (fail-closed if unavailable); xhdfe_info() reports the CUDA arch the package was built for.

For a network-disabled installation from xhdfe-src.zip or the autonomous offline bundle, install the pinned Rcpp source into a local library first:

mkdir -p r/Rlib
R_PROFILE_USER=/dev/null R_ENVIRON_USER=/dev/null \
  R_LIBS_USER="$PWD/r/Rlib" \
  R CMD INSTALL --library="$PWD/r/Rlib" third_party/Rcpp_1.1.2.tar.gz
R_PROFILE_USER=/dev/null R_ENVIRON_USER=/dev/null \
  R_LIBS_USER="$PWD/r/Rlib" XHDFE_ENABLE_CUDA=OFF \
  R CMD INSTALL --library="$PWD/r/Rlib" r/xhdfe

The unmodified CRAN archive's URL, license, version, and SHA-256 are recorded in third_party/RCPP_SOURCE_PROVENANCE.md.

Minimal example (a small simulated worker–firm panel):

library(xhdfe)

set.seed(2026)
n <- 600
d <- data.frame(
  worker = sample(80, n, replace = TRUE),
  firm   = sample(30, n, replace = TRUE),
  x1     = rnorm(n),
  x2     = rnorm(n)
)
d$y <- 0.5 * d$x1 - 0.2 * d$x2 + 0.05 * d$worker + 0.03 * d$firm + rnorm(n)

# Two-way fixed effects (worker + firm), clustered by firm
m <- xhdfe(y ~ x1 + x2 | worker + firm, data = d, cluster = ~ firm)
summary(m)

# Optional: request CUDA after installing a CUDA-enabled build
m_gpu <- xhdfe(y ~ x1 + x2 | worker + firm, data = d,
               cluster = ~ firm, backend = "cuda")
stopifnot(m_gpu$gpu_used == 1, m_gpu$gpu_status == "used")

The R formula grammar is fixest-style: y ~ x | fe1 + fe2 for absorbed FEs, fe[slope] / fe[[slope]] for heterogeneous slopes, f1^f2 for a combined interaction FE, and | endo ~ inst for IV. See r/README.md for the CUDA build and the platform note, and ?xhdfe for the full documentation.


Worker-firm (AKM) and Gelbach post-estimation

Beyond general-purpose HDFE regression, xhdfe ships a worker-firm layer that follows the Kline-Saggio-Sølvsten (2020) leave-out methodology (validated against Saggio's LeaveOutTwoWay and pytwoway) and a Gelbach (2016) decomposition — all on the same compiled backend, in Stata, Python and R. Installation is the same as the core (they are part of the one package).

Stata:

* leave-one-out connected set, then the AKM/KSS variance decomposition
xhdfeconnected worker firm, generate(insample)
xhdfeakm y, worker(worker) firm(firm) ci          // KSS SEs + Andrews-Mikusheva CIs
xhdfegelbach y, x1(educ) x2groups("skill = ability") fes(firm)

Python:

import xhdfe.akm as akm, xhdfe.gelbach as gelbach
r = akm.akm_kss(y, worker, firm, compute_se=True, eigen_diagnostics=True)
print(r["kss"], r["component_se"], r["weak_id"])
g = gelbach.decompose(y, educ, x2_groups={"skill": ability}, fes={"firm": firm})

R:

fit <- xhdfe_akm_kss(y, worker, firm, compute_se = TRUE, eigen_diagnostics = TRUE)
g   <- xhdfe_gelbach(y, x1 = educ, x2_groups = list(skill = ability),
                     fes = list(firm = firm))

Gelbach's standard mode accounts for the movement from one base linear model to one full model. The separate absorbed-target mode covers a declared X1 target that belongs to an added FE span: its full coefficient is imposed at zero and explicitly labelled, never treated as an estimated within-FE effect. Inference for that target must be clustered at the absorbing FE dimension.

Version 1.5.0 supports multiple focal coefficients, multiple observed blocks, HDFEs common to both models, and any number of added FE dimensions. Its joint-covariance inference includes denominator uncertainty and the cross-covariance term in shares(base) in Stata and share = "base" in Python/R; the earlier base_fixed convention remains available as descriptive fixed-denominator scaling. Results expose retained-sample provenance, mobility-connectivity checks for supported two-way designs, weak-denominator and regularity diagnostics, observed-block full-model coefficients, and truthful CUDA-use metadata.

The reporting layer can fully refit the model under iid- or cluster-pairs bootstrap draws and produce tables, coefficient plots, and waterfall data. Use xhdfegelbachbootstrap, xhdfegelbachetable, and xhdfegelbachcoefplot in Stata; gelbach.bootstrap, gelbach.etable, gelbach.waterfall_data, and gelbach.coefplot in Python; or the corresponding xhdfe_gelbach_* functions in R.

Run help xhdfegelbach, python -m xhdfe gelbach, or ?xhdfe_gelbach for the complete estimands, covariance layout, warnings, reporting helpers, examples, and deliberate limits. The decomposition is specification accounting, not evidence of causal mediation.

The plug-in, AGSU (homoskedastic) and KSS (heteroskedasticity-robust leave-out) decompositions report the variance of worker effects, of firm effects, their covariance and correlation, and the shares of wage variance; with se/ci they add component standard errors and Andrews-Mikusheva weak-identification confidence intervals. Exact and Johnson-Lindenstrauss leverages, frequency weights and an optional CUDA solver are supported. Runnable examples in all three languages live in examples/; a felsdvsimul walkthrough is in docs/akm-kss.md.

In Stata, xhdfeakm 1.7.2 reports a single affected-row count when many non-stayer observations hit the unit-leverage guard. This is a bounded diagnostic change; it does not alter KSS estimates, tolerances, or convergence decisions.


Repository layout

Path Contents
src/, include/, third_party/ The shared C++ core and vendored build inputs: Eigen and pybind11 sources plus the pinned official Rcpp source archive used by autonomous offline release media.
python/, xhdfe/ Python package (import xhdfe; the HdfeRegressor class).
r/ R package (r/xhdfe/), examples, and helper tools.
stata/ Stata package: xhdfe.ado, xfe.ado, help files, plugin sources (src/), and build scripts (tools/).
tests/ tests/stata/: Stata certification and smoke tests; tests/validation/: Python oracle and cross-frontend validators; tests/benchmarks/: public benchmark replication.
docs/ Quickstart and overview.
CMakeLists.txt, pyproject.toml, setup.py Build configuration for the C++ core and Python bindings.

Documentation

  • Quickstart & overview: docs/quickstart.md, docs/overview.md.
  • GPU (CUDA): docs/gpu.md — install-with-GPU, request, and verify in Stata/Python/R.
  • AKM + leave-out (KSS) & Gelbach: docs/akm-kss.md; help xhdfeakm, help xhdfeconnected, help xhdfegelbach, help xhdfegelbachbootstrap, help xhdfegelbachetable, help xhdfegelbachcoefplot, python -m xhdfe gelbach, and ?xhdfe_gelbach.
  • Release workflow: docs/release-workflow.md.
  • Release history and certification: docs/releases/, docs/certification/.
  • Stata: help xhdfe, help xfe.
  • R: ?xhdfe, ?fixef.xhdfe, ?predict.xhdfe; feature tour in r/examples/.
  • Python: python -m xhdfe or xhdfe-help at the shell, or xhdfe.help_text() inside Python.

Validation & accuracy

Under the default reghdfe-comparable tolerance mode, xhdfe coefficients, standard errors, and recovered fixed effects match reghdfe at the same nominal tolerance (down to the conditioning of the problem). The three packages are cross-checked against each other and against the wider ecosystem — reghdfe (Stata), fixest (R), pyfixest (Python), and FixedEffectModels.jl (Julia). This software is released as a proof of concept: please validate estimates for your own research design. See DISCLAIMER.md.

Citation

If you use xhdfe in academic work, please cite it (see CITATION.cff):

Portela, Miguel, and Tiago Tavares. 2026. xhdfe: High-dimensional fixed effects regression via a C++ backend. Version 2.24.1. https://github.com/reisportela/xhdfe-xfe

License

MIT — see LICENSE. xhdfe bundles the Eigen 3.4.0 headers (primarily MPL-2.0, with parts under BSD-3-Clause and Apache-2.0); see NOTICE. Autonomous release media also carry the unmodified official Rcpp 1.1.2 source archive under its upstream GPL (>= 2) license solely as the R package's offline build dependency; see third_party/RCPP_SOURCE_PROVENANCE.md.

Authors

  • Miguel Portela — NIPE / Universidade do Minho and BPLIM / Banco de Portugal.
  • Tiago Tavares — NIPE / Universidade do Minho.

Development note: xhdfe was built with AI-assisted tooling, but only the two listed humans are authors; no software tool or AI system is credited as an author or co-author.

Acknowledgements

xhdfe validates against and interoperates with prior HDFE software. Full credit goes to reghdfe by Sergio Correia (Stata), fixest by Laurent Berge (R), pyfixest by Alexander Fischer and collaborators (Python), and FixedEffectModels.jl by Matthieu Gomez and collaborators (Julia).

By design, xhdfe is first and foremost a high-performance replica of reghdfe: it mirrors reghdfe's estimator, defaults, and reporting, and reghdfe-comparable results are its reference. From the worker-firm (AKM) literature and from pytwoway — Thibaut Lamadon and Adam A. Oppenheimer's reference Python toolkit for two-way worker-firm models (AKM and the leave-out, CRE and BLM estimators) — xhdfe adopts only what adds value inside that reghdfe universe: the leave-out (KSS) bias-corrected variance decomposition, the leave-out connected set, and the Gelbach decomposition, implemented natively on the same C++ core. It does not attempt to reproduce pytwoway.

xhdfe links to pytwoway in two concrete ways. First, validation: its leave-out decomposition is checked at machine precision against pytwoway and against LeaveOutTwoWay by Raffaele Saggio, the canonical Kline-Saggio-Sølvsten (2020) implementation. Second, interoperability: xhdfe exports the leave-out sample to the pytwoway / bipartitepandas format, so a cleaned two-way sample moves between the two tools. The combination is most useful in labour economics with large linked employer-employee data: run the fast HDFE regression and the leave-out variance decomposition (variance of worker and firm effects, their covariance, and worker-firm sorting) inside a familiar reghdfe workflow with xhdfe, and reach for pytwoway when you need its broader structural models (CRE, BLM) that are deliberately outside xhdfe's scope. The Gelbach decomposition is validated against b1x2 by Jonah Gelbach. Full credit to their authors.

We thank Paulo Guimaraes, Marta Silva, and Nelson Areal for discussions and workshop collaboration around earlier versions of the project. We especially thank Sergio Correia for feedback on benchmarking, tolerances, and reghdfe-comparable validation. We also warmly thank Alexander Fischer for sharing the latest updates on his and Kristof Schröder's novel graph-based fixed-effects demeaning strategy — a modified LSMR solver with an additive-Schwarz preconditioner built from the worker-firm bipartite graph (the within project) — which has been very helpful for our ongoing work on high-dimensional demeaning. All remaining errors are ours.

References

High-dimensional fixed effects — the reghdfe universe xhdfe replicates:

  • Cornelissen, T. 2008. The Stata command felsdvreg to fit a linear model with two high-dimensional fixed effects. Stata Journal 8(2): 170-189.
  • Guimaraes, P., and P. Portugal. 2010. A simple feasible procedure to fit models with high-dimensional fixed effects. Stata Journal 10(4): 628-649.
  • Gaure, S. 2013. OLS with multiple high dimensional category variables. Computational Statistics & Data Analysis 66: 8-18.
  • Correia, S. 2016. reghdfe: Estimating linear models with multi-way fixed effects. Stata Conference, Stata Users Group.
  • Correia, S., P. Guimaraes, and T. Zylkin. 2020. Fast Poisson estimation with high-dimensional fixed effects. Stata Journal 20(1): 95-115.

Worker-firm (AKM) leave-out layer — what xhdfe borrows from the pytwoway literature (see Acknowledgements):

  • Abowd, J. M., F. Kramarz, and D. N. Margolis. 1999. High wage workers and high wage firms. Econometrica 67(2): 251-333. (AKM two-way model.)
  • Andrews, M. J., L. Gill, T. Schank, and R. Upward. 2008. High wage workers and low wage firms: negative assortative matching or limited mobility bias? Journal of the Royal Statistical Society A 171(3): 673-697. (AGSU homoskedastic correction.)
  • Kline, P., R. Saggio, and M. Sølvsten. 2020. Leave-out estimation of variance components. Econometrica 88(5): 1859-1898. (KSS leave-out heteroskedasticity-robust correction and inference.)
  • Andrews, I., and A. Mikusheva. 2016. A geometric approach to nonlinear econometric models. Econometrica 84(3): 1249-1264. (Weak-identification q=1 confidence intervals used by KSS.)
  • Gelbach, J. B. 2016. When do covariates matter? And which ones, and how much? Journal of Labor Economics 34(2): 509-543. (Conditional decomposition of coefficient movements.)

Contributing

Contributions, bug reports, and validation cases are welcome — see CONTRIBUTING.md.

Platform support

The C++ core, Python bindings, and R package target Linux x86-64, Windows x86-64, and macOS Apple Silicon/Intel source builds with the local platform toolchain. CUDA GPU acceleration is optional on Linux with the NVIDIA toolkit. The online Stata net-install site provides CPU plugins. Certified releases may also provide separate Linux CUDA fatbin plugins alongside Linux CPU/OpenMP, Windows x86-64 CPU/OpenMP, and macOS universal assets. Machine-specific CUDA plugins can be built from source on Linux with the NVIDIA toolkit.

About

Linear regression with multiple high-dimensional fixed effects, in Stata, Python and R on one C++ core (reghdfe-comparable; optional CUDA)

Topics

Resources

Contributing

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages