<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Statistics on Volundarhus</title><link>http://www.volundarhus.com/categories/statistics/</link><description>Recent content in Statistics on Volundarhus</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 22 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://www.volundarhus.com/categories/statistics/index.xml" rel="self" type="application/rss+xml"/><item><title>Marginal Effects for StatsModels: A Stata-style `margins` in Python</title><link>http://www.volundarhus.com/posts/smmargins/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><guid>http://www.volundarhus.com/posts/smmargins/</guid><description>&lt;p&gt;If you&amp;rsquo;ve ever moved from Stata to Python and reached for &lt;code&gt;margins, dydx(*) at(age=(25 45 65))&lt;/code&gt;, you know the feeling. StatsModels has &lt;code&gt;get_margeff&lt;/code&gt;, but it&amp;rsquo;s narrow: average or at-means, continuous variables, a couple of model classes. The moment you want a marginal effect &lt;em&gt;at a specific covariate profile&lt;/em&gt;, or a discrete change for a factor, or a difference-in-differences on the probability scale of a logit, you&amp;rsquo;re on your own.&lt;/p&gt;
&lt;p&gt;So I wrote a small module — &lt;a href="#" &gt;&lt;code&gt;marginal_effects.py&lt;/code&gt;&lt;/a&gt; — that fills in the gap. This post is a tour of what it does, the math that makes it work, and the design decisions that kept it small.&lt;/p&gt;</description></item></channel></rss>