Skip to content

Instantly share code, notes, and snippets.

View apoorvalal's full-sized avatar

Apoorva Lal apoorvalal

View GitHub Profile
# %%
import functools
from typing import Callable, TypeVar, Any
import pandas as pd
import numpy as np
T = TypeVar("T")
# %%
@apoorvalal
apoorvalal / linRegressionInference.R
Last active June 3, 2024 05:03
Inference for the Population Average Treatment Effect using fully interacted OLS
library(momentfit); library(car); library(tictoc)
set.seed(42)
# %%
dgp = \(n=500, k = 2){
X = matrix(rnorm(n * 2), n, 2)
Y1 = X[, 1] + X[, 1]^2 + runif(n, -0.5, 0.5)
Y0 = X[, 2] + X[, 2]^2 + runif(n, -1, 1)
Z = rbinom(n, 1, 0.6)
Y = Z * Y1 + (1-Z) * Y0
data.frame(Y, Z, X)
from joblib import Parallel, delayed
import numpy as np
import pandas as pd
class LinearMediation:
def __init__(self):
pass
def fit(self, X, W, y, store=True):
@apoorvalal
apoorvalal / texJanus.tex
Last active January 20, 2024 02:25
generate both an article and slide-deck from the same tex file using beamerswitch.
\documentclass[%
article,
% beamer,
beameroptions={ignorenonframetext,14pt},
articleoptions={a4paper,12pt},
also={trans,handout,article}
]{beamerswitch}
\handoutlayout{nup=3plus,border=1pt}
\articlelayout{maketitle,frametitles=none}
\mode<article>{\usepackage[hmargin=2cm,vmargin=2cm]{geometry}}
@apoorvalal
apoorvalal / ml_powered_covariate_adjustment.py
Created December 20, 2023 01:45
covariate adjustment using nonparametric regression (Wager et al 2016 PNAS)
import numpy as np
import pandas as pd
from scipy.stats import norm
from sklearn.model_selection import cross_val_predict, KFold
# learners
from xgboost import XGBRegressor
from glum import GeneralizedLinearRegressorCV
from sklearn.kernel_ridge import KernelRidge
@apoorvalal
apoorvalal / fwl_estimates_and_se.R
Created December 8, 2023 20:16
numerical verification of equality of coefficient and SE per FWL
library(estimatr)
data(auto)
# %% FWL regression coefficient
auto$ytil = lm(price ~ displacement, auto)$resid
auto$x2til = lm(weight ~ displacement, auto)$resid
(fwlest = lm_robust(ytil ~ x2til, auto, se_type = "HC0")
%>% summary %>% .$coefficients %>% .[2, 1:2])
# %%
(fullest =
lm_robust(price ~ weight + displacement, auto, se_type = "HC0") %>%
@apoorvalal
apoorvalal / ols_lean.py
Created November 5, 2023 17:21
lean implementation of OLS
import numpy as np
from scipy.linalg import lstsq
np.random.seed(42)
# %%
def ols(X, y, vcov = 'HC1', driver = 'gelsy'):
"""
Fast, minimal implementation of least squares regression with robust SEs
Args:
X: n X p array of covariates
@apoorvalal
apoorvalal / simulate_adjustment_strategies.R
Last active November 2, 2023 22:53
compare bias and variance properties of regression adjustment strategies https://www.degruyter.com/document/doi/10.1515/ijb-2021-0072/html
# %%
pacman::p_load(knitr, tidyverse, DeclareDesign, glmnet)
set.seed(42)
# %% estimator functions
p_hacker = function(data) {
fit_1 = lm_robust(Y ~ Z + X1, data = data)
fit_3 = lm_robust(Y ~ Z + X1 + X2, data = data)
fit_2 = lm_robust(Y ~ Z + X2 + X3 + X4, data = data)
fit_4 = lm_robust(Y ~ Z + X3 + X4 + X5 + X6 + X7 + X8 + X9, data = data)
@apoorvalal
apoorvalal / panel_balancing.R
Last active May 29, 2023 03:08
simulator to compare did/sc/sdid/augsynth/eb/ebhr for ATT estimation in panel settings
pacman::p_load(synthdid, ebal, glue, augsynth, MCPanel, glue)
# needs https://github.com/apoorvalal/ebal - solves ebal problem in torch - far more stable than old version
# remotes::install_github("apoorvalal/ebal")
# %% simulator for panel balancing
#' @param n number of units
#' @param t number of time periods
#' @param parallel_trends boolean for parallel trends
#' @param random_assignment boolean for random assignment of treatment
#' @param σ noise level in mapping from factor to outcome
@apoorvalal
apoorvalal / OB_ATT.R
Created December 1, 2022 14:52
R Code for Kline (2011) - KOB as a reweighting estimator.
# %% # obs lalonde data from Kline paper - init housekeeping
libreq(data.table, fixest, rio)
cps3 = import("cps3re74.dta") %>% setDT() %>% na.omit()
setnames(cps3, c("re78", "treat"), c("y", "W"));
xs = setdiff(colnames(cps3), c("y", 'W'))
W = cps3$W %>% as.matrix(); Y = cps3$y %>% as.matrix()
X = cbind(1, cps3[, ..xs]) %>% as.matrix()
X1 = X[W==1,]; X0 = X[W==0,]
N = length(W); N_t = sum(W)
# %% first way - KOB / kline - page 1