<jupyter_start><jupyter_text>WelcomeThis is material for the **Synthetic Control** chapter in Scott Cunningham's book, [Causal Inference: The Mixtape.](https://mixtape.scunning.com/)<jupyter_code>%%capture
# This cell installs some utility packages. We utilize R via rpy2.

from rpy2.robjects.packages import importr
from rpy2.robjects.conversion import localconverter
utils = importr('utils')
utils.install_packages('Synth')
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf

from rpy2 import robjects
from rpy2.robjects import pandas2ri
pandas2ri.activate()
from rpy2.robjects.vectors import IntVector

import plotnine as p
import matplotlib.pyplot as plt

%matplotlib inline


import ssl
ssl._create_default_https_context = ssl._create_unverified_context

def read_data(file):
    full_path = "https://raw.github.com/scunning1975/mixtape/master/" + file
    
    return pd.read_stata(full_path)<jupyter_output><empty_output><jupyter_text>Prison Construction and Black Male Incarceration<jupyter_code>texas = read_data("texas.dta")
Synth = importr('Synth')
control_units = [1, 2, 4, 5, 6] +\
    list(range(8, 14)) + list(range(15,43)) +\
    list(range(44, 47)) + [49, 50, 51, 53,54,55,56]

robjects.globalenv['texas'] = texas

predictors = robjects.vectors.StrVector(['poverty', 'income'])
sp = robjects.vectors.ListVector({'1': ['bmprison', IntVector([1988, 1990, 1991, 1992]), 'mean'], 
                                  '2': ['alcohol', 1990, 'mean'], 
                                  '3': ['aidscapita', IntVector([1990, 1991]), 'mean'], 
                                  '4': ['black', IntVector([1990, 1991, 1992]), 'mean'], 
                                  '5': ['perc1519', 1990, 'mean']})

dataprep_out = Synth.dataprep(texas, 
    predictors = predictors,
    predictors_op="mean",
    time_predictors_prior=np.arange(1985, 1994),
    special_predictors=sp,
    dependent='bmprison',
    unit_variable='statefip',
    unit_names_variable='state',
    time_variable='year',
    treatment_identifier=48,
    controls_identifier=control_units,
    time_optimize_ssr=np.arange(1985, 1994),
    time_plot=np.arange(1985, 2001))

synth_out = Synth.synth(data_prep_obj = dataprep_out)
weights = synth_out.rx['solution.w'][0]
ct_weights = pd.DataFrame({'ct_weights':weights.flatten(), 'statefip':control_units})
ct_weights.head()
texas = pd.merge(ct_weights, texas, how='right', on='statefip')
texas = texas.sort_values('year')
ct = texas.groupby('year').apply(lambda x : np.sum(x['ct_weights']*x['bmprison']))
treated = texas[texas.statefip==48]['bmprison'].values
years = texas.year.unique()


plt.plot(years, ct, linestyle='--', color='black', label='control')
plt.plot(years, treated, linestyle='-', color='black', label='treated')
plt.legend()
plt.ylabel('bmprison')
plt.xlabel('Time')
plt.title('Synthetic Control Performance')
plt.axvline(1993, linestyle = 'dashed', color = 'black')
plt.show()
ct_diff = treated - ct

plt.plot(years, np.zeros(len(years)), linestyle='--', color='black', label='control')
plt.plot(years, ct_diff, linestyle='-', color='black', label='treated')
plt.legend()
plt.ylabel('bmprison')
plt.xlabel('Time')
plt.title('Gaps: Treated - Synthetic')
plt.axvline(1993, linestyle = 'dashed', color = 'black')
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15559545182525433, 'fraction_numerical': 0.03949730700179533, 'mean_word_length': 4.82404181184669, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '288947', 'license': 'MIT', 'n_tokens_mistral': 1301, 'n_tokens_neox': 1135, 'n_words': 232, 'path': 'Synthetic_Control.ipynb', 'repo_name': 'scunning1975/python-mixtape', 'size': '3342'}