Introduction ============ ``smmargins`` is a small module that fills in the marginal-effects gaps in `StatsModels `_: adjusted predictions and marginal effects at user-specified covariate profiles, with delta-method standard errors, for *any* fitted model that exposes ``params``, ``cov_params()``, and a ``predict(params, exog)`` method. The design target is `Stata's `_ ``margins`` command: the same statistics, the same parameter names where they translate, and the same answers to the precision both tools agree on. Why another margins module? --------------------------- StatsModels ships ``Results.get_margeff``, but it is limited: - only marginal effects, not adjusted predictions; - ``atexog`` is keyed by *column index*, not variable name; - no ``at(...)`` profiles, no representative-value contrasts; - no joint covariance across statistics, so you cannot form contrasts like a difference-in-differences without re-deriving the delta method by hand; - no support for difference-in-differences on the response scale (the Ai & Norton 2003 issue). Installation ------------ .. code-block:: bash pip install smmargins Requires Python ≥3.9. Dependencies (``numpy``, ``pandas``, ``statsmodels``, ``scipy``, ``patsy``) are installed automatically. Quickstart ---------- .. code-block:: python import statsmodels.formula.api as smf from smmargins import Margins fit = smf.logit( "voted ~ age + income + C(educ) + female + age:female", data=df, ).fit() M = Margins(fit) # Adjusted predictions M.predict() # AAP M.predict(at="mean") # APM (margins, atmeans) M.predict(atexog={"age": [25, 45, 65]}) # APR # Marginal effects on the response (probability) scale M.dydx("age") # AME M.dydx("age", at="mean") # MEM M.dydx("age", atexog={"female": [0, 1]}) # MER, by sex M.dydx("educ", reference="college") # discrete contrasts # Difference-in-differences on the response scale res = M.did("group", "preexist_Y", group_levels=["A", "B"], condition_levels=[0, 1]) print(res) # cells, simple effects, DiD # Alternative VCEs and robust covariance M.dydx("age", cov_type="HC3") # heteroskedastic-robust M.dydx("age", vce="simulation", n_sims=2000, sim_seed=0) # Krinsky–Robb M.dydx("age", vce="bootstrap", n_boot=1000, boot_seed=0) # pairs bootstrap # Simultaneous CIs across a family of three predictions M.predict(atexog={"age": [25, 45, 65]}, vce="simulation", n_sims=4000, ci_method="sup-t") Each call returns a :class:`~smmargins.MarginsResult` with ``.estimate``, ``.se``, ``.vcov``, ``.ci_lower``, ``.ci_upper``, ``.pvalue``, plus ``.summary()`` returning a :class:`pandas.DataFrame`. Pass ``use_t=True`` to the :class:`~smmargins.Margins` constructor for t-distribution inference (uses ``results.df_resid``). Observation weights ------------------- Pass weights at construction. ``weight_type="sampling"`` (default) or ``"frequency"``. WLS-fitted results respect their fit-time weights when ``weights=None``; explicit ``weights=`` overrides and warns. Bootstrap resampling uses weight-proportional draws under sampling weights. .. code-block:: python M = Margins(fit, weights=w) M = Margins(fit, weights=counts, weight_type="frequency") Where to next ------------- **Tutorials — learn by doing.** - :doc:`tutorials/getting_started` — install, fit, first AAP and AME. - :doc:`tutorials/adjusted_predictions` — ``at=``, ``atexog=``, scales. - :doc:`tutorials/marginal_effects` — continuous, discrete, elasticities. - :doc:`tutorials/inference` — delta vs KR vs bootstrap, simultaneous CIs. - :doc:`tutorials/did` — 2x2 difference-in-differences end-to-end. - :doc:`tutorials/counterfactuals_and_plotting` — ``newdata=``, ``Expr``, the plotting API. **How-to guides — task-focused recipes.** - Robust covariance: :doc:`howto/robust_clustered_ses`. - Alternative VCEs: :doc:`howto/kr_simulation`, :doc:`howto/bootstrap`, :doc:`howto/simultaneous_ci`. - Multi-outcome models: :doc:`howto/multi_outcome_models`. - Subgroup AMEs and joint tests: :doc:`howto/subgroup_analysis`, :doc:`howto/joint_tests_pairwise`. - Custom scales: :doc:`howto/custom_transforms`, :doc:`howto/elasticities`. - Counterfactuals and plotting: :doc:`howto/counterfactual_predictions`, :doc:`howto/expr_and_values`, :doc:`howto/plotting`. - Validation and modes: :doc:`howto/verify_against_r`, :doc:`howto/formula_vs_raw`. **Explanations — theory and design.** - :doc:`math` — delta method, statistic schema, analytic vs FD Jacobian. - :doc:`explanations/scales_link_functions`, :doc:`explanations/discrete_vs_continuous`, :doc:`explanations/outer_jacobian`. - :doc:`explanations/patsy_design_rebuilding`, :doc:`explanations/formula_vs_raw_mode`, :doc:`explanations/expr_and_values`. - :doc:`explanations/inference_comparison`, :doc:`explanations/multiple_comparisons`, :doc:`explanations/contrast_joint_covariance`. - :doc:`explanations/ai_norton_did` — why DiD belongs on the response scale. **Reference.** - :doc:`api` — every public class and method. - :doc:`demos` — full Williams-style and DiD walkthroughs from the repository root.