Skip to content

Instantly share code, notes, and snippets.

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
@apoorvalal
apoorvalal / synth_andor_did.R
Created November 17, 2022 20:09
did, synth, and synthetic did in CVXR
library(CVXR); library(data.table)
# %% functions
# reshape panel data from long to wide for factor models / outcomes
panelMatrices = function(dt, unit_id, time_id, treat, outcome) {
dt = as.data.table(dt)
# function to extract first column, convert it to rownames for a matrix
matfy = function(X) {
idnames = as.character(X[[1]])
X2 = as.matrix(X[, -1])
@apoorvalal
apoorvalal / neymanAllocationStrata.R
Last active August 22, 2022 23:04
Compute optimal treatment assignment for treatment effect precision
#' Compute Neyman allocation propensity scores for inference-optimal treatment assignment in data table [very fast]
#' @param df data.table
#' @param y outcome name
#' @param w treatment name
#' @param x covariate names (must all be discrete)
#' @return data.table with strata level conditional means, variances, propensity scores,
#' and neyman allocation propensities.
#' @export
neymanAllocation = function(df, y, w, x){
df1 = copy(df); N = nrow(df1)