statsmodels icon indicating copy to clipboard operation
statsmodels copied to clipboard

[ENH] Add Great Tables export for regression results (Results.as_gt())

Open sisird864 opened this issue 6 months ago • 4 comments

Is your feature request related to a problem? Please describe

Many users need publication-quality regression tables for papers, reports, and notebooks/Quarto. The existing .summary() text/HTML/LaTeX outputs are helpful, but reaching journal-style tables typically requires additional manual formatting and post-processing. A direct bridge from Results objects to a high-level table library would streamline reproducible workflows.

Describe the solution you'd like

Add a first-class export path from statsmodels Results objects to the Great Tables Python package:

  • API:
    • New method: Results.as_gt() returning a GT object (optional dependency).
    • Initially support common result classes: OLS/GLM/Logit/Probit; design API so more models can be added.
  • Content mapping:
    • Columns: coefficient, std. error, test statistic (t or z), p-value, and confidence interval.
    • Model-level stats in header/footnotes: N, R² (or pseudo-R²), AIC, BIC, log-likelihood, etc.
  • Options:
    • Significance markers, decimal formatting, variable/term labeling, column spanners, notes/footnotes.
    • Multi-model stacking (e.g., helper to combine multiple Results into one table).
  • Packaging:
    • Keep Great Tables as an optional dependency; if not installed, raise a clear ImportError with an install hint.
  • Tests & docs:
    • Unit tests (including smoke tests) for supported models and options.
    • A gallery/example notebook rendering the table to HTML/PDF.

Describe alternatives you have considered

  • Using .summary() (text/HTML/LaTeX) and then hand-tuning formatting and layout; this works but is verbose and brittle for repeated use.
  • Exporting values to pandas DataFrames and building tables manually; flexible but requires users to re-implement common conventions (e.g., stars, CI formatting, model stats).
  • Third-party exporters or custom scripts that duplicate logic across projects.

Additional context

  • Happy to implement this feature and open a WIP PR for early API review.
  • Open questions for maintainers:
    • Preferred location: a method on Results vs. a helper in statsmodels.iolib.
    • Exact set of model-level statistics to include by default for each family.
    • Defaults for significance notation and number formatting.
  • Backwards compatibility: this is additive and opt-in; no changes to existing .summary() behavior are proposed.

sisird864 avatar Aug 02 '25 16:08 sisird864

This would be great. You should take a look at how Great Tables was integrated with Polars. Perhaps a similar approach could work here.

https://posit-dev.github.io/great-tables/blog/polars-dot-style/

joshhilton avatar Sep 06 '25 15:09 joshhilton

Hi all,

We (actually @dsliwka) have just released maketables to PyPi. It spun out of PyFixest and creates regression tables for models from statsmodels, linearmodelsand pyfixest using great-tables.

docs: link github: link

Here is the sm example from the docs:

import pandas as pd
import maketables as mt

import statsmodels.formula.api as smf
# Load your data (here using a sample Stata dataset with the import_dta function that also stores variable labels)
df = mt.import_dta("https://www.stata-press.com/data/r18/auto.dta")

# Generate a dummy variable and label it
df["foreign_i"] = (df["foreign"] == "Foreign")*1
mt.set_var_labels(df, {"foreign_i": "Foreign (indicator)"})

# Fit your models 
est1 = smf.ols("foreign_i ~ weight + length + price", data=df).fit()
est2 = smf.probit("foreign_i ~ weight + length + price", data=df).fit(disp=0)

# Make the table
mt.ETable([est1, est2], model_stats=["N","r2","pseudo_r2"], 
          model_heads=["OLS","Probit"],
          caption="Regression Results (Statsmodels)")

which produces the following figure:

Image

One core feature of the library is that it can support models from different packages in one table:

import pyfixest as pf 

# Here we just reestimaate the linear probability model using pyfixest instead of statsmodels
est0=pf.feols("foreign_i ~ weight + length + price", data=df)

# Make the table
mt.ETable([est0, est1, est2], model_stats=["N","r2","pseudo_r2"], 
          model_heads=["OLS (PyFixest)","OLS (Statsmodels)","Probit"],
          caption="Regression Results combining different packages")

which produces

Image

Due to a modular design akin to R's modelsummary, it should be fairly easy to add new model classes / estimators.

You can of course install it via pip install maketables.

Any feedback and help (in particular, support for new model classes) is of course more than welcome!

cc @bashtage because of linear models support =)

s3alfisc avatar Nov 20 '25 20:11 s3alfisc

This looks great!

ChadFulton avatar Nov 20 '25 20:11 ChadFulton

Very nice!

bashtage avatar Nov 20 '25 21:11 bashtage