Skip to content

Implement dbivreg (compress, moments, and demean)#66

Open
jamesbrandecon wants to merge 6 commits into
mainfrom
implement-dbivreg
Open

Implement dbivreg (compress, moments, and demean)#66
jamesbrandecon wants to merge 6 commits into
mainfrom
implement-dbivreg

Conversation

@jamesbrandecon

Copy link
Copy Markdown
Collaborator

Ok here is a first PR @grantmcdermott. So far I've only gotten demean and moments implemented. compress should be straightforward, but it was getting to be a lot of code so I wanted to get it on remote for you and copilot to review. The structure is pretty similar to dbreg.R and the API should be close to fixest. Let me know what you think, and whether you want to stack compress (and mundlak?) into the same PR or not.

Some example code if you want to test:

pkgload::load_all(".")
library(fixest)

# Simulate dataset with two-way structure for all specs
set.seed(3)
dat = expand.grid(unit = 1:25, time = 1:6)
dat$fe1 = factor(dat$unit)
dat$fe2 = factor(dat$time)
dat$cluster = factor(dat$unit)
dat$x = rnorm(nrow(dat))
dat$z = rnorm(nrow(dat))
dat$w = runif(nrow(dat), 0.5, 2)

alpha = rnorm(25)[dat$unit]
tau = rnorm(6)[dat$time]
v = rnorm(nrow(dat))
dat$d = 0.9 * dat$z + 0.4 * dat$x + alpha + tau + v
dat$y = 2.0 * dat$d + 0.5 * dat$x + alpha + tau + 0.6 * v + rnorm(nrow(dat))

# 1. No fixed effects, IID SEs
db_iid = dbivreg(y ~ x | d ~ z, data = dat, vcov = "iid", strategy = "moments")
fx_iid = feols(y ~ x | d ~ z, data = dat, vcov = "iid")

# 2. No fixed effects, weighted HC1 SEs
db_hc1 = dbivreg(y ~ x | d ~ z, data = dat, weights = "w", vcov = "hc1", strategy = "moments")
fx_hc1 = feols(y ~ x | d ~ z, data = dat, weights = ~w, vcov = "hc1")

# 3. No fixed effects, clustered SEs
db_cl = dbivreg(y ~ x | d ~ z, data = dat, weights = "w", vcov = ~cluster, strategy = "moments")
fx_cl = feols(y ~ x | d ~ z, data = dat, weights = ~w, vcov = ~cluster)

# 4. One-way fixed effects, weighted HC1 SEs
db_fe = dbivreg(y ~ x | fe1 | d ~ z, data = dat, weights = "w", vcov = "hc1", strategy = "demean")
fx_fe = feols(y ~ x | fe1 | d ~ z, data = dat, weights = ~w, vcov = "hc1")
check_iv_match(db_fe, fx_fe)

# 5. Two-way fixed effects, IID SEs
db_tw = dbivreg(y ~ x | fe1 + fe2 | d ~ z, data = dat, vcov = "iid", strategy = "demean")
fx_tw = feols(y ~ x | fe1 + fe2 | d ~ z, data = dat, vcov = "iid")

@jamesbrandecon jamesbrandecon changed the title Implement dbivreg Implement dbivreg (compress and demean) May 21, 2026
@jamesbrandecon

Copy link
Copy Markdown
Collaborator Author

@copilot Review this PR. Look in particular for anywhere that something is defined for dbivreg where we should be re-using utils and functions from dbreg.

Agent-Logs-Url: https://github.com/grantmcdermott/dbreg/sessions/43981276-c1f0-43f0-8cbe-fd2163bb3748

Co-authored-by: jamesbrandecon <62019331+jamesbrandecon@users.noreply.github.com>

Copilot AI commented May 21, 2026

Copy link
Copy Markdown
Contributor

@copilot Review this PR. Look in particular for anywhere that something is defined for dbivreg where we should be re-using utils and functions from dbreg.

Addressed. I reviewed dbivreg for shared-utility reuse and replaced dbivreg-specific vcov label formatting with a shared helper in R/utils.R (format_vcov_label), then wired both print.dbreg, print.dbivreg, and IV first-stage labeling to it. Commit: 35af85c.

@grantmcdermott

Copy link
Copy Markdown
Owner

Great, thanks. I'm out for Memorial Day weekend, so will be a bit before I can review. Ideally, we'd support all strategies out of the gate, but let me get back to you once I've looked at the code.

@jamesbrandecon jamesbrandecon changed the title Implement dbivreg (compress and demean) Implement dbivreg (compress, moments, and demean) May 27, 2026
@jamesbrandecon

Copy link
Copy Markdown
Collaborator Author

Ok I added the compress strat, which seemed mostly straightforward. The mundlak one is where I'm still iffy. Maybe you know more about mundlak than I do, but I've never seen it done in IV and I haven't convinced myself that codex is right about its proposal being sound.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants