# Replication Baskaran & Hessami (2018)

This notebook contains a replication of [Baskaran, T., & Hessami, Z. (2018) Does the Election of a Female Leader Clear the Way for More Women in Politics? *American Economic Journal: Economic Policy*, 10(3): 91-121](https://www.aeaweb.org/articles?id=10.1257/pol.20170045).

For this purpose, first, I present an executive summary on the article, including the research hypothesis, analyzed data and the used method. Nonetheless, I strongly recommend that one reads the original article prior to reading this notebook. Second, descriptive and graphical data analyses are presented. This is useful for understanding and making sense of the data that is used for the empirical analysis and serves as a preparation for the third part of this notebook: A replication of the key results of the paper. Besides the baseline results of the main model this includes econometric analyses regarding the internal validity of the used method as well as the robustness tests presented in the article. Subsequently, the fourth section of this notebook presents an investigation on the internal validity of the regression discontinuitiy design (henceforth RD design) which goes beyond what is presented in the article. Finally, section 5 concludes the results of this exercise.

Naturally, throughout this replication I draw heavily from the original article. Unless stated otherwise, the reader should, therefore, assume that the ideas presented within this notebook are reproductions of the contents of Baskaran & Hessami (2018).

Overall, the results presented by Baskeran & Hessami (2018) can successfully be replicated. Particularly, the baseline results of the main estimation model, the test results for internal validity of the econometric method, and the results for robustness tests yield the same results in this replication as in the article.

Table of Contents

1. Excecutive summary of the paper

2. Descriptive and Graphical Analyses

2.1. Description of the Dataset

2.2. Discontinuity in Distribution of Observations

2.3. Discontinuity at the Critical Value of the Margin of Victory

3. Replication and Critical Review

3.1 Graphical Evidence: RDD Plot

3.2 Main Results

3.2.1 Regression Results

3.2.2 Robustness

3.2.2.1 Placebo Test

3.2.2.2 Scaling of the Outcome Variable

3.3 Internal Validity of the RD Design

3.3.1 Pretreatment Municipality Characteristics

3.3.2 Discontinuity in Density

3.3.3. Confoundness with Mayor Ideology

4. Independent Contribution: On Internal Validity of the RD Design

5. Conclusions

References

## 1. Excecutive summary of the paper
* **Theoretical Framework:** *Anti-female voter bias* results in underrepresentation of females in politics.

* **Research Hypothesis:** Exposure to a female mayor deminishes *anti-female biases* of voters.

**Figure 1: Causal Graph**

* **Identification problems:**

    * Other potential drivers of the underrepresentation of femeales in politics:
        - Political parties influence election outcomes. Thus, underrepresentation might be caused by *anti-female party biases*.
        - Parties might *anticipate anti-female voter bias* and, therefore, are less willing to field female candidates in competitive races.
        - Women who expect discrimination might be reluctand to run for election/ pursue a career in politics in the first place.

    * Isolating *anti-female voter bias*: Rule out alternative explanations:
        - (a) Initial rank of female candidates does not impact their rank advancements.
        - (b) Characteristics of women on party's list chage only little in case there is a female mayor in office.
        - (c) Number of female candidates on list remains unchanged.
        - (a), (b), and (c) indicate little *anti-female party bias*.

* **Data:**

    * Data on local council election in the German state of Hesse:
        - Open-list electoral system (parties specify order of candidates; voters can distribute preferential votes to individual candidates).
        - Includes gender, list ranks, personal characteristics among other information for ~109.017 candidates who competed in 2001, 2006, 2011, or 2016 elections.

    * Data on mayor elections for all 426 municipalities in Hesse
        - Including the elected mayor's gender and the margin the election was won by.
        - Including characteristics of each municipality.

* **Method:**

    * Authors use a RD design to study the causal effects of female mayors on subsequent council election results.

    * The discontinuity is provided by close mixed-gender mayor elections. Authors compare "candidate's rank improvement of women in municipalities where a woman barely won against a man with outcomes in municipalities where a man barely won against a woman".

    * Estimated model equation:
     \begin{align}
     rank \, improvement_{k, i, t} = \alpha + \beta female \, mayor_{i, t} + f(vote \, margin)_{i, t} + female \, mayor_{i, t} \times  g(vote \, margin)_{i, t} + \epsilon_{k, i, t} \tag{1}
     \end{align}

     Where
         - $rank \, improvement_{k, i, t}$ is the normalized rank improvement of candidate $k$ in municipality $i$ and local election year $t$.
         - $vote \, margin_{i, t}$ is the margin of victory of the female candidate in the preceeding mayoral election (negative values, thus, denote a loss of the female candidate).
         - $female \, mayor_{i, t}$ is a dummy that takes value 1 if a female candiate has won the mayoral election preceeding the council election $(female \, mayor_{i, t} = 1 \Leftrightarrow vote \, margin_{i, t} > 0)$.

* **Results:**
    * A female candidate winning a close mixed-gender mayoral election causes:

        - Voters to give preferential votes to female council candidates.

        - A 4 percentage points higher share of female council members.

        - Positive spillover effects on female council candidates in neighboring municipalities.

```python
# Import packages and auxiliary functions
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

from scipy.stats import ttest_ind

from auxiliary.localreg import *
from auxiliary.auxiliary_functions import *
from auxiliary.plots_and_figures import *

# General notebooks settings
pd.options.display.max_columns = None

# Settings for matlibplot package
plt.rc('axes', axisbelow=True)

# Import auxiliary datasets
df_mayor_election_data = pd.read_stata('data/mayor_election_data.dta')
df_municipality_characteristics = pd.read_stata('data/municipality_characteristics_data.dta')
df_mayor_election_data = pd.read_stata('data/mayor_election_data.dta')
df_placebo = pd.read_stata('data/dataset_with_lagged_rank_improvments.dta')

# Import main dataset and print a few randomly seleted rows for illustration
df_main_dataset = pd.read_stata('data/main_dataset.dta')
df_main_dataset.sample(5)

```

      gkz
      jahr
      gkz_jahr
      rdd_sample
      female
      elected
      gewinn_norm
      gewinn
      gewinn_dummy
      listenplatz_norm
      joint_party
      age
      non_university_phd
      university
      phd
      architect
      businessmanwoman
      engineer
      lawyer
      civil_administration
      teacher
      employed
      selfemployed
      student
      retired
      housewifehusband
      incumbent_council
      wahlbet
      party
      female_mayor
      margin_1
      inter_1
      margin_2
      inter_2
      female_mayor_full_sample
      sum_years_as_mayor
      mayor_age
      mayor_university
      mayor_employment
      log_bevoelkerung
      log_flaeche
      log_debt_pc
      log_tottaxrev_pc
      log_gemeinde_beschaef_pc
      log_female_sh_gem_besch
      log_tot_beschaeft_pc
      log_female_share_totbesch
      log_prod_share_tot
      log_female_share_prod

      33708
      436004
      2011.0
      4360042011
      1.0
      0.0
      0.0
      8.108109
      3.0
      1.0
      72.972977
      1.0
      51.0
      0.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      47.5
      spd
      0.0
      -12.3
      0.0
      151.290009
      0.00000
      0.0
      4.0
      56.0
      1.0
      0.0
      9.920246
      3.133318
      -0.121231
      -0.156653
      -5.091933
      -0.820981
      -1.721057
      -0.828959
      -1.353310
      -0.962557

      12539
      432003
      2001.0
      4320032001
      NaN
      0.0
      1.0
      12.000000
      3.0
      1.0
      20.000000
      0.0
      54.0
      0.0
      1.0
      0.0
      0.0
      0.0
      1.0
      0.0
      0.0
      0.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      57.3
      fdp
      NaN
      NaN
      NaN
      NaN
      NaN
      0.0
      NaN
      NaN
      NaN
      NaN
      8.574329
      2.225704
      -0.585786
      -0.040672
      -5.483287
      -0.893818
      -2.000649
      -0.715747
      -1.105620
      -1.177601

      333
      411000
      2001.0
      4110002001
      NaN
      0.0
      0.0
      -12.676056
      -9.0
      0.0
      47.887325
      0.0
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      NaN
      0.0
      49.5
      fdp
      NaN
      NaN
      NaN
      NaN
      NaN
      0.0
      NaN
      NaN
      NaN
      NaN
      11.836761
      4.805904
      0.732735
      -0.134298
      -3.653085
      -0.719740
      -0.456145
      -0.820801
      -1.224465
      -1.244217

      89078
      633001
      2001.0
      6330012001
      1.0
      1.0
      1.0
      22.580645
      7.0
      1.0
      58.064518
      1.0
      22.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      59.2
      spd
      1.0
      24.9
      24.9
      620.010010
      620.01001
      1.0
      4.0
      43.0
      0.0
      1.0
      9.025455
      2.892037
      -0.455480
      -0.564198
      -5.387869
      -1.335001
      -2.531702
      -0.719202
      -1.190449
      -1.589733

      41061
      438001
      2006.0
      4380012006
      NaN
      0.0
      0.0
      2.222222
      1.0
      1.0
      22.222221
      0.0
      71.0
      1.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      1.0
      0.0
      0.0
      43.2
      rep
      NaN
      NaN
      NaN
      NaN
      NaN
      0.0
      NaN
      NaN
      NaN
      NaN
      10.415203
      3.075929
      0.347201
      -0.105884
      -4.791185
      -0.620071
      -1.165065
      -0.896876
      -1.526133
      -1.257860

## 2. Descriptive and Graphical Analyses
This section presents a descriptive summary of the data set which is provided by the authors. First, the coverage of the data set is described, i.e., how many council and mayor elections are observed for what number of municipalities and other rather superficial properties. We will have a look at the compositions of this data set, particularly in relation to the subsample of female council candidates which will be of increased interest throughout article and, hence, for this replication.

Second, we will try to make sense of observable discontinuities in observations. When inspecting the data set, in particular the observations for margin of victory and rank improvement combinations, noticeable discontinuities in both dimensions can be seen. This is especially interesting, because these discontinuities lead to stacked observations in a scatter plot which, in term, make it hard to judge if there is a discontinuity around the cutoff value of margin of victory.

This section concludes with a summary of the insights that can be gained from this very top level descriptive approach as well as the finding, that a discontinuity around the cutoff yet needs to be identified.

### 2.1. Description of the Dataset
The data set contains observations on 1721 mayor elections. This includes the margin of victory as well as the gender of the mayoral candidates. Out of these 1721 elections, 268 are classified as a *mixed gender election*. The term *mixed gender election* is defined by the authors as "mayor elections \[where\] the top two candidates were of opposite gender".

At the same time, observations on the election results of 109.017 council candidates are provided. When only those council candidates are kept in the sample which ran at an election that was preceded by a mixed gender mayor election, a total of 23.169 council candidates is observed. For each of these candidate's individual characteristics like gender, education and occupation as well as their success in the council election is observed. Success in a council election is measured by the normalized rank improvement, which will be looked at in more detail in subsection 2.2.

```python
# Count of mayor elections
descriptive_dict = {}
descriptive_dict["mayor_election_count"] = df_mayor_election_data["mayor_election_year"].count()

# Count of mixed gender elections
descriptive_dict["mixed_gender_elections_count"] = df_mayor_election_data["rdd_sample"].sum()

# Count of council candidates
descriptive_dict["council_candidates_count"] = df_main_dataset.gkz_jahr.count().astype(str)

# Count of council candidates in mixed gender election municipality
descriptive_dict["relevant_council_candidates_count"] = df_main_dataset.rdd_sample.count()

# print results
for k in descriptive_dict.keys():
    print(k, ":", descriptive_dict[k], "\n")
```

    mayor_election_count : 1721

    mixed_gender_elections_count : 268.0

    council_candidates_count : 109017

    relevant_council_candidates_count : 23169

```python
# Generate a Barchart presenting the number of municipalities for which observations are available and for the
# number of candidates per gender.
plot_observations_municipalities_candidates(df_main_dataset)

# Calculate the total number of Municipalities
muni_count = df_mayor_election_data.gkz.nunique()
print("In total there is data on characteristics available for",
      "{} different Hessian Municipalities".format(muni_count)
     )
```

    In total there is data on characteristics available for 426 different Hessian Municipalities

Availability of administrative data on municipalities (i.e. their population, per capita tax revenues and employment among others) is worse in early years. It is available for all 426 municipalities in 2016, however, for in 2001 it is available for 199 municipalities, only (figure 2, left side). While data for 2016 was provided by The Statistical Office of Hesse, data for previous years come "from varying internet sources such as municipalities' websites as well as e-mail communication with the mayors, their administrative assistants, and high-ranking officials in the local administration." The quality of this information, thus, cannot be verified.

A similar pattern in availability can be seen for the number of candidates observed in each year. The share of female candidates seems to be relatively stable at approximately 25 % in each year (figure 2, right side).

**Figure 2: Number of observations on municipalities (left) and candidates per year (right)**

Data on the characteristics of council candidates varies slightly in availability. The data set provided by the authors contains information on educational attainment for 48.729 candidates. The occupation is provided for 49.399 individuals and age is known for 54.676 candidates (see table below for summary statistics). Differences in characteristics of council candidates are analyzed in the context section 5 of the article, where this information is used to assess the mechanisms that potentially drive the results of the main model. These mechanisms, however, are beyond the scope of this replication.

```python
# Calculate a descriptive summary table using a function stored in the auxiliary/plots_and_fígures file
summary_stats(df_main_dataset)
```

    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

      All candidates
      Female candidates

      Count
      Mean
      SD
      Min
      Max
      Count
      Mean
      SD
      Min
      Max

      gewinn_norm
      109017
      0.0666775
      13.2524
      -89.1892
      97.2973
      28480
      -0.458681
      11.9338
      -89.1892
      97.2973

      age
      54676
      51.5807
      13.7804
      18
      102
      13923
      51.035
      13.6026
      18
      96

      non_university_phd
      48729
      0.650578
      0.476758
      0
      1
      11734
      0.671723
      0.469591
      0
      1

      university
      48729
      0.281598
      0.449675
      0
      1
      11734
      0.277399
      0.447711
      0
      1

      phd
      48729
      0.0678241
      0.25149
      0
      1
      11734
      0.0508778
      0.219755
      0
      1

      architect
      49399
      0.00860341
      0.092334
      0
      1
      11832
      0.00693036
      0.0829653
      0
      1

      businessmanwoman
      49399
      0.0758922
      0.264901
      0
      1
      11832
      0.0641481
      0.245015
      0
      1

      engineer
      49399
      0.0553048
      0.228622
      0
      1
      11832
      0.0138607
      0.116922
      0
      1

      lawyer
      49399
      0.0313772
      0.174319
      0
      1
      11832
      0.0351589
      0.184205
      0
      1

      civil_administration
      49399
      0.0773093
      0.26701
      0
      1
      11832
      0.0581474
      0.23403
      0
      1

      teacher
      49399
      0.051661
      0.221369
      0
      1
      11832
      0.0781778
      0.268453
      0
      1

      employed
      55416
      0.714721
      0.451489
      0
      1
      14043
      0.697501
      0.459378
      0
      1

      selfemployed
      55416
      0.0584669
      0.234624
      0
      1
      14043
      0.0361746
      0.186739
      0
      1

      student
      55416
      0.0443915
      0.205934
      0
      1
      14043
      0.0516271
      0.221288
      0
      1

      retired
      55416
      0.14393
      0.350939
      0
      1
      14043
      0.112868
      0.316428
      0
      1

      housewifehusband
      55416
      0.0228995
      0.149591
      0
      1
      14043
      0.0880154
      0.283326
      0
      1

This table compares characteristics of council candidates and their success in the council election between the whole sample and the female subsample. There are noticeable differences in the first row "gewinn_norm" which provides data on the normalized rank improvement of a candidate. By showing a lower (even negative) rank improvement on average, females appear to be less successful in council elections than male candidates.

While most of the candidates' characteristics seem to be quite similar in both groups, there is some noticeable differences when it comes to the candidates' occupations: While the share of engineers is six times higher in the whole sample then among females, more than four times as many women than men reported domestic work as their occupation (category "housewifehusband").Furthermore, there is smaller but still noticeable differences, e.g. in occupations "selfemployed" and "retired" (both taking higher shares for male candidates) as well as "teacher" and "civil_administration" (both higher for female candidates).

Overall, especially with respect to age and education of the candidates, there seems to be relatively little differences as seen from this descriptive level of inspection.

### 2.2. Discontinuity in Distribution of Observations
Taking a step beyond the content of the article, this section presents a brief investigation of the observations that are provided on the margin of victory (MoV) of a female in a mixed-gender mayor election and the rank improvements of female council candidates. This will help to get a feeling for the data on this main interrelation, prior to the econometric analyses that will be presented in subsequent sections of this notebook.

The relationship between the MoV of the female mayor (abscissa) and the rank improvements of female candidates in the subsequent council election (ordinate) is illustrated in firgure 2 below. For this exercise, only data on council elections that is subsequent to mixed-gender mayor elections will be used. In addition, only rank improvements of female council candidates are of interest for this analysis and, therefore, are included in the illustration below.

Note that for easier interpretability *rank improvements* in the council elections are provided in a normalized form, facilitating comparability of changes in ranks of candidates between councils of different sizes. This conversion follows equation (2) of the article:

\begin{align}
    rank \, improvement = (\frac{initial \, rank - final \, rank}{council \, size}) \times 100 \label{eq2} \tag{2}
\end{align}

```python
# Create a dataset that only contains observations on (a) on rank improvements of female council candidates and
# (b) mixed gender mayor elections.
rdd_data = df_main_dataset.loc[(df_main_dataset.female == 1) &
                               (df_main_dataset.rdd_sample == 1)
                              ]

# Create a scatter plot that shows all combinations of the margin of victory of a female in a mixed
# gender mayor lection and the rank improvements of female candidates in subsequent council elections.
# Function is stored in auxiliary/plots_and_figures
plot_observations(df=rdd_data, s=0.1)

## Auxiliary addition: Find the reason for the discrete changes in gewinn_norm.
# This would make sense, if the council sizes are small and many councils have same sizes.
# Thus, create a plot showing the distribution of council sizes

# Deduce the councile size using previously introduced conversion to normalizesd rank improvements.
council_sizes = rdd_data[['gkz_jahr', 'gewinn_norm', 'gewinn', 'listenplatz_norm']].copy()
council_sizes.loc[:,'council_size'] = council_sizes.loc[:,'gewinn'] / council_sizes.loc[:,'gewinn_norm'] * 100

# drop rows where gewinn = 0 since we cannot deduct on council sizes in these cases.
council_sizes.drop(labels=council_sizes.loc[council_sizes.loc[:, 'gewinn']==0,:].index,
                   axis=0,
                   inplace=True
                  )

# Calculate the 95% percentile of council sizes as well as the number of councils that were voted for.
N_councils = len(council_sizes.drop_duplicates(subset=['gkz_jahr'])['council_size'])
percentile = int(np.percentile(a=council_sizes.drop_duplicates(subset=['gkz_jahr'])['council_size'],
                               q=95, interpolation='lower'
                              ))

# plot a histogram for the council sizes
bins = int((council_sizes['council_size']).max() - (council_sizes['council_size']).min())

hist_council_sizes(df=council_sizes, bins=bins)
print('The number of council elections that we have observations for is '+
      '{}. \nThe 95 % percentile of council sizes is {}.'.format(N_councils, percentile))
```

    The number of council elections that we have observations for is 214.
    The 95 % percentile of council sizes is 45.

Figure 3 displays the rank improvement of a female council candidate and the MoV of a female mayor in the preceding mixed-gender mayor election. Since a lot of observations are stacked on top of each other and to prevent the figure from being too cluttered, a random sample of 10% of all available observations is plotted. Looking at the distributions of observed combinations, a pattern of horizontally as well as vertically aligned data points is revealed.

First, since the authors work with a data set that contains rank improvements of each female council candidate for a given result of the preceding mayor election, discrete changes in the horizontal dimension, i.e. for mayor election results, are no surprising considering the limited number of observed mayor elections.

Second, the discrete distribution of values in the vertical dimension can be explained when a closer look is taken at the distribution of council sizes: As previously described, rank improvements are normalized using the respective size of the council. While the authors do not provide data on the council sizes, this value can easily be deduced from the given values for absolute and relative gains in list ranks for the candidates. As presented in figure 4, sizes of the 214 observed councils are distributed over relatively few values and are clustered at certain values. In addition, 95% if all councils have not more than 45 seats.

Concluding, it seems plausible to observe a discrete distribution of normalized rank improvements, given the discussed distribution of council sizes which will cause the denominator for the value on the ordinate to be the same for a large number of observations.

**Figure 3: Sample observations on normalized rank improvements and margin of victory**

**Figure 4: Distribution of council sizes**

### 2.3. Discontinuity at the Critical Value of the Margin of Victory
Considering figure 3, it is not very obvious if there is a discontinuity around the critical value of margin of victory (i.e. a margin of 0). A jump in values on the ordinate, however, might not be visible in this graphical representation. As discussed previously, observations are not distributed continuously but instead show strong discontinuities. This might result in a lot of observations being stacked on top of each other, hence not being represented in above plot. However, this problem should be mitigated by plotting only a small fraction of 10% of all observations.

Summarizing, a discontinuity around the cutoff can still not be ruled out. Hence, in another approach we will have a look at binned data. By plotting data tuples of the mean values of both, the margin of victory as well as the rank improvement, a discontinuity should be revealed (if there is any). This is because stacked observations will still have an impact of equal size on the mean values within each bin. In the next section, this approach of plotting binned data will be pursued further.

## 3. Replication and Critical Review
### 3.1 Graphical Evidence: RDD Plot

As seen in previous section, a clear discontinuity around the cutoff value of the margin of victory of 0 is hard - if at all - to spot in figure 3 presented above. Hence, a more promising approach is presented by the authors in *Figure 2: Rank Improvement of Female Candidates* of the article which is an RDD-plot for binned normalized rank improvements. A replication of this RDD-plot is displayed in figure 5 below.

In this plot, first, the running variable (female mayor candidate margin of victory) is limited o values from -30 to +30 %. This allows to focus on the part of the data which is most relevant for this analysis. Second, the authors decide to bin the observations into clusters of 3 percentage points width of the running variable. Third, local polynomial regression of the underlying observations is added (red line) estimating the relation of both variables. Finally, the pointwise 95% confidence intervals are illustrated as black lines.

```python
# Keep only observations that fir above described criteria
rdd_plot_data = rdd_data.loc[(rdd_data.margin_1 >= -30) & (rdd_data.margin_1 <= 30)].copy()

# Create the RDD plot using the function stored in the auxiliary file.
rslt = rdd_plot(data=rdd_plot_data, x_variable="margin_1", y_variable="gewinn_norm", nbins=20, ylimits=(-6,6), width=20.1, deg=1)
```

The regression discontinuity plot reveals a discontinuity at the cutoff value, i.e. a MoV of 0. Since a python package for the calculation of confidence intervals of a local polynomial regression is currently not available, I calculate pointwise confidence intervals. The results of this graphical analysis can be seen as a confirmation of the existence of a discontinuity at the cutoff value which is argued by the authors.

### 3.2 Main Results
#### 3.2.1 Regression Results

After previous section provided graphical evidence on the existence and the extent of the discontinuity in rank improvements around the cutoff value of the MoV, this section replicates the results of a regression discontinuity analysis that aims to estimate the causal effect of a female mayor on success of female council candidates.

For the estimation of the effect of a female mayor on the success of a female council candidates, two different approaches are presented. The first relates gender of incumbent mayor to the normalized rank improvement of female candidates (i.e., normalized rank improvements are endogenous). The second relates gender of incumbent mayor to the likelihood that an elected member of the council in the same municipality is female (i.e. a dummy that equals 1 for council members that are female is endogenous).

Both regressions are performed using different bandwidths and functional forms. For this replication, I will focus on the main specification (highlighted in bold font) which is the basis for the discussion in the article.

* a) bandwidths:
    - **optimal CCT bandwidth (20.1)**
    - CCT / 2 (10.05)
    - CCT * 2 (40.2)
    - IK (35.59)
* b) functional form:
    - **linear**
    - quadratic

Only the optimal CCT bandwidth is used for the quadratic specification resulting in five specifications in total. The second approach results in insignificant results while point estimates seem to be in line with the results of the first approach. Since the subsequent discussion in mainly based on the first specification it will be calculated by default in the following cells. Note that the results for different bandwidths can easily be reproduced by adjusting the *bw* variable in subsequent code cells.

For further information on the chosen bandwidth selection criteria (CCT), the documentation of [rdrobust](https://d1e153b2-a-62cb3a1a-s-sites.googlegroups.com/site/rdpackages/rdrobust/stata/rdrobust.pdf?attachauth=ANoY7coYcDVv4k7XCZ-Kf0Mm5vUExsMu1m4V1ETm955F5qt8DADN1vnHjmhHjyvzwVWcN63n5F1PYajyeTnm1jsbwo16IirwoemO_u9o-USoBOAWOJPOVLTvew_zk1tToB_YI7rEiYhCSCDe98NIZ1M-RpQWaRD5aTCa8pOi2S2ivyMx08GvdcSe0bEbRsI9q_HYs_L7vmEH1E2qTTbJCDwy646Glx3uJVhGS4Ft6C_QP4fsX0Rp1wQ%3D&attredirects=0), the stata package that is used by the authors, can be consulted.

**Specification 1: Rank Improvements of Female Candidates:**

In this specification normalized rank improvements are endogenous in the margin of victory of a female mayor, a dummy that takes value 1 if a female won the mayor election and an interaction term of both, margin and dummy. The regression model is illustrated in equation (3) below. In this notation, $i$ denotes one female council candidate. The dummy $D_{f\_mayor, i}$ takes value 1 if the mayor in charge at the time of the council election is female. Finally, $MoV$ denotes the margin of victory of the female mayor candidate. Note that for values bigger 0 for $MoV$, $D_{f\_mayor, i}$ takes value 1 and vice versa.

\begin{align}
    normalized\_rank\_improvement_i = \beta_0 + \beta_1 D_{f\_mayor, i} + \beta_2 MoV_i + \beta_3 D_{f\_mayor, i} * MoV_i \tag{3}
\end{align}

Additionally, observations are weighted using their distance to the cutoff value of 0 for the margin of victory. Lower weights are attached to observations farther away from the cutoff value. Thus, observations very close to the cutoff will have a weight close to 1. At the same time, observations where the size of the margin of victory close to the size of the bandwidth will have a weight close to 0.

```python
# Set the bandwidth (taken from the paper)
bw = 20.1

# Get regression weights
rdd_data["weight"] = calculate_weights(df=rdd_data, bandwidth=bw)

# Run regression for approach (1): normalized rank improvement of female candidates on gender of mayor
sm.WLS(endog=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn_norm"],
       exog=sm.add_constant(rdd_data.loc[abs(rdd_data["margin_1"])<bw][["female_mayor", "margin_1", "inter_1"]]),
       weights=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gkz"]}
            ).summary()
```

    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:5: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      """
    C:\ProgramData\Anaconda3\lib\site-packages\numpy\core\fromnumeric.py:2389: FutureWarning: Method .ptp is deprecated and will be removed in a future version. Use numpy.ptp instead.
      return ptp(axis=axis, out=out, **kwargs)

WLS Regression Results

  Dep. Variable:	       gewinn_norm	     R-squared:         	    0.011

  Model:	                   WLS	         Adj. R-squared:    	    0.010

  Method:	             Least Squares	    F-statistic:       	    5.982

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	  0.00133

  Time:	                 01:33:17	       Log-Likelihood:    	  -11259.

  No. Observations:	        2878	        AIC:               	 2.253e+04

  Df Residuals:	            2874	        BIC:               	 2.255e+04

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	           -1.0352	     0.584	    -1.772	  0.076	    -2.180	     0.110

  female_mayor	     3.7118	     0.980	     3.788	  0.000	     1.791	     5.632

  margin_1	        -0.0689	     0.068	    -1.007	  0.314	    -0.203	     0.065

  inter_1	         -0.1210	     0.104	    -1.164	  0.245	    -0.325	     0.083

  Omnibus:	       990.914	   Durbin-Watson:     	    2.062

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 11077.674

  Skew:	           1.304	    Prob(JB):          	     0.00

  Kurtosis:	      12.251	    Cond. No.          	     40.4

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

Comparing the results presented in the paper (see figure 6 below) to the regression summary above, it can be seen that the results presented in the article can be replicated. As eluded to earlier, the authors present a number of different specifications for varying bandwidths as well as functional forms. The results of the main model (optimal bandwidth and linear functional form) can be seen in the column denoted with (1) in the figure below.

The presented results for varying bandwidths can easily be replicated by adjusting the *bw* variable in the code cell above to take the according value in row "Bandwidth size" of figure 6. While the resulting estimates as well as the number of observations and other outputs can be replicated for specifications (1) through (4), the quadratic functional form (specification (5)) cannot be estimated due to limitations in the functional form of the python package used for this estimation.

The quadratic specification, however, acts merely as another robustness check for the main results. As seen in figure 6 below, changes in the functional form (i.e. adding the squared versions of the third and fourth summand on the right hand side of equation (3)) does not result in substantial changes in the regression outcome. The point estimate remains at approximately the same level and still shows to be significant at the 95% level.

**Figure 6: Main results I: Rank improvement of female candidates as presented by the authors**

```python
# Descriptives of the regression result
N = rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn_norm"].count()
elec = rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gkz_jahr"].nunique()
muni = rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gkz"].nunique()
y_mean = rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn_norm"].mean()
y_sd = rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn_norm"].std()
main_result_descriptive = pd.DataFrame(data=[N, elec, muni, y_mean, y_sd],
                                       index=["Observations",
                                              "Elections",
                                              "Municipalities",
                                              "Dep. Variable Mean",
                                              "Dep. Variable SD"
                                             ],
                                       columns = ["value"],
                                      )

# print the results
main_result_descriptive
```

      value

      Observations
      2878.000000

      Elections
      77.000000

      Municipalities
      56.000000

      Dep. Variable Mean
      0.411436

      Dep. Variable SD
      10.949259

As a check for mistakes in the replication process, the descriptive statistics which the authors provide with the main result (see figure 6 above), are replicated as well. All descriptive values calculated for the data used in the replication process match with their counterparts presented by the authors. Thus, there is no reason to believe that the underlying observations of the regression analysis are different from the ones used by the authors of the article.

The results of this regression analysis indicate that the victory of a female candidate in the mayoral election in a municipality is associated with an improvement of 3.7 normalized ranks. For the median council size of 31 seats this corresponds to approximately 1.15 ranks.

**Approach 2: Share of Women among Candidates Elected to the Council:**

For the second approach, the gender of an elected council member is used as the endogenous variable while the right side of the regression equation remains the same. Althogh the endogenous variable is a binary variable in this regression equation, the authors apply the same weighted linear regression method which is used in the first approach presented above. Thus, the estimated model can be denoted as follows.

\begin{align}
    D_{gender\_council\_candidate,i} = \beta_0 + \beta_1 D_{f\_mayor, i} + \beta_2 MoV_i + \beta_3 D_{f\_mayor, i} * MoV_i  \tag{4}
\end{align}

Note that the right hand side of equation (4) remains unchanged in comparison to the previously discussed specification presented in equation (3). The binary endogenous variable $D_{gender\_council\_candidate,i}$ takes value 1 if candidate $i$ is female and 0 otherwise.

At the same time, the data set used for this regression model is slightly different from the one used previously. While it includes data on male as well as female council candidates now, it only contains those of council candidates that end up to be elected into council.

```python
# Select data on (a) mixed gender mayor elections and (b) council candidates who were elected
candidates_elected = df_main_dataset.loc[(df_main_dataset.rdd_sample == 1) & (df_main_dataset.elected == 1)].copy()

# set same bandwidth as authors do
bw = 23.90

# Add weighing vector as calculated by the authors
candidates_elected["weight"] = calculate_weights(df=candidates_elected, bandwidth=bw)

# Run regression for approach (2): Gender of an elected council candidate
sm.WLS(endog=candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["female"],
       exog=sm.add_constant(
           candidates_elected.loc[abs(candidates_elected["margin_1"])<bw][["female_mayor",
                                                                           "margin_1",
                                                                           "inter_1"
                                                                          ]]
       ),
       weights=candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["gkz"]}
            ).summary()
```

WLS Regression Results

  Dep. Variable:	         female	        R-squared:         	    0.001

  Model:	                   WLS	         Adj. R-squared:    	    0.000

  Method:	             Least Squares	    F-statistic:       	   0.4036

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	   0.751

  Time:	                 01:33:17	       Log-Likelihood:    	  -2654.2

  No. Observations:	        3463	        AIC:               	    5316.

  Df Residuals:	            3459	        BIC:               	    5341.

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	            0.2563	     0.021	    12.210	  0.000	     0.215	     0.297

  female_mayor	     0.0412	     0.042	     0.990	  0.322	    -0.040	     0.123

  margin_1	        -0.0004	     0.002	    -0.204	  0.839	    -0.004	     0.003

  inter_1	         -0.0006	     0.003	    -0.193	  0.847	    -0.007	     0.005

  Omnibus:	       522.050	   Durbin-Watson:     	    1.918

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	  765.517

  Skew:	           1.140	    Prob(JB):          	 5.89e-167

  Kurtosis:	       2.666	    Cond. No.          	     40.1

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

Again, the results of this regression correspond to the results presented in the article (see figure 7 below). Similar to the replication of the first approach presented earlier, the regression summary is set to replicate the main results, hence, uses the optimal bandwidth and a linear functional form as presented in column (1) of figure 7 below. However, by setting the according value for the *bw* variable, specifications (2) through (4) can be replicated from the code block above effortlessly.

**Figure 7: Main results II: Share of women among candidates elected to the council as presented by the authors**

The main result provides a point estimate of 0.041 which indicates that the voctory of a female mayor candidate in a mixed gender election is associated with a 4.1 percentage points increase in the share of female council members.

```python
# Calculate descriptives
N = candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["female"].count()
elec = candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["gkz_jahr"].nunique()
muni = candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["gkz"].nunique()
y_mean = candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["female"].mean()
y_sd = candidates_elected.loc[abs(candidates_elected["margin_1"])<bw]["female"].std()
main_result_descriptive = pd.DataFrame(data=[N, elec, muni, y_mean, y_sd],
                                       index=["Observations",
                                              "Elections",
                                              "Municipalities",
                                              "Dep. Variable Mean",
                                              "Dep. Variable SD"
                                             ],
                                       columns = ["value"],
                                      )

# print the results
main_result_descriptive
```

      value

      Observations
      3463.000000

      Elections
      96.000000

      Municipalities
      72.000000

      Dep. Variable Mean
      0.273751

      Dep. Variable SD
      0.445954

#### 3.2.2 Robustness
In order to evaluate the robustness of their baseline results, the authors present two different approaches: First, a placebo test and, second, a test for different scalings of the outcome variable. The authors argue that, overall, the baseline results show to be robust to both of these checks.

##### 3.2.2.1 Placebo Test
The placebo test is described to check whether past values of the outcome variable "can be explained by contemporaneous values of the treatment variable". Applied to the analysis presented in the article, this translates to a test for statistically significant correlations between the gender of the mayor in council election period $t$ and the rank improvements of female council candidates in period $t-k$. The authors argue that "if the female mayor dummy has a significant effect on the rank improvements of women in past elections, this would call our baseline estimates into question."

Time lag $k$ is chosen to be five by the authors, which amounts exactly to the time between two council elections ([Hessian Municipal Code §36](http://www.lexsoft.de/cgi-bin/lexsoft/justizportal_nrw.cgi?t=156459931255666006&sessionID=1855059091299078653&chosenIndex=Dummy_nv_68&templateID=document&source=context&source=context&highlighting=off&xid=146137,46)). This assumption is not discussed in the article, although it is somewhat questionable since the regular period of office of a mayor in Hesse is six years ([Hessian Municipal Code, §39](http://www.lexsoft.de/cgi-bin/lexsoft/justizportal_nrw.cgi?xid=146137,50)). By setting $k=5$ the authos ensure that a mayor is in office for at most one year before the council election takes place. Thus, mitigating effects on anti-female voters bias arguably are quite low. At the same time, one could argue that the effects of a female mayor on anti-female voters bias might be particularly large right after the mayor's election while media coverage of the mayor might be especially broad and while the election itself is not in the too distant past.

Indeed, as shown in the next cell, only for 40% of the observations used in the placebo test, the mayor is in charge for less than five years at the moment the council election takes place. In other words, voters have been exposed to the same mayor in the council election in year $t$ that was already in charge during the council election in year $t-5$ in 60% of the observations. Hence, the results of the placebo test as it is presented by the authors might be imprecise.

Next, the placebo test as it is depicted in the article is replicated. Subsequently, leaving the scope of a replication for a moment, a placebo test based on a stricter data selection than the one presented by the authors is carried out. Both these analyses are conducted using the placebo dataset ("dataset_with_lagged_rank_improvments.dta") which is provided by the authors. This dataset contains information on the mayor's gender and MoV at time $t$ as well as results for the council election in $t-5$.

```python
# Is the longer office term of mayors a relevant problem?
# If the mayor is in office for 5 or more years at t (time of council election) then
# he/ she was in charge during last council election -> no real placebo test!
# How many mayors where in office for 5 or more years at time t, when t is the year of council election?

# Merge placebo date with data on the sum of years a mayor is in office at year t
df_placebo_2 = pd.merge(left=df_placebo,
                  right=df_main_dataset[[
                      "gkz_jahr",
                      "sum_years_as_mayor"
                  ]].drop_duplicates(),
                  on=["gkz_jahr"],
                  how="left")

# calculate share of observations with a mayor that is in office for less
# then 5 years in all observations used in placebo test
temp = np.round(
    len(df_placebo_2.loc[df_placebo_2["sum_years_as_mayor"]<5,:].index) / len(df_placebo_2.index),
    3
)
print("The mayor in office is in charge for less than five years for {}%".format(temp)+
      " of the observations on the placebo dataset.")
```

    The mayor in office is in charge for less than five years for 0.401% of the observations on the placebo dataset.

```python
# Replicate the placebo test as it is performed and presented in the article

# Set the bandwidth (taken from the paper)
bw = 15.71 # CCT
#bw = 15.71/2
#bw = 15.71*2
#bw = 17.22 # KI

# Get regression weights
df_placebo["weight"] = calculate_weights(df=df_placebo, bandwidth=bw)

# Run regression of rank improvements in t-5 on mayor election result in t
sm.WLS(endog=df_placebo.loc[abs(df_placebo["margin_1"])<bw]["gewinn_norm"],
       exog=sm.add_constant(df_placebo.loc[abs(df_placebo["margin_1"])<bw][[
           "female_mayor",
           "margin_1",
           "inter_1"
       ]]),
       weights=df_placebo.loc[abs(df_placebo["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":df_placebo.loc[abs(df_placebo["margin_1"])<bw]["gkz"]}
            ).summary()
```

WLS Regression Results

  Dep. Variable:	       gewinn_norm	     R-squared:         	    0.006

  Model:	                   WLS	         Adj. R-squared:    	    0.004

  Method:	             Least Squares	    F-statistic:       	    1.590

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	   0.206

  Time:	                 01:33:17	       Log-Likelihood:    	  -6293.4

  No. Observations:	        1603	        AIC:               	 1.259e+04

  Df Residuals:	            1599	        BIC:               	 1.262e+04

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	           -0.2475	     0.763	    -0.324	  0.746	    -1.743	     1.248

  female_mayor	     0.8003	     1.365	     0.586	  0.558	    -1.875	     3.476

  margin_1	         0.0117	     0.105	     0.112	  0.911	    -0.193	     0.217

  inter_1	          0.1117	     0.161	     0.695	  0.487	    -0.203	     0.427

  Omnibus:	       674.912	   Durbin-Watson:     	    2.037

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 8634.893

  Skew:	           1.609	    Prob(JB):          	     0.00

  Kurtosis:	      13.905	    Cond. No.          	     32.2

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

```python
# placebo test with only those observations from placebo dataframe in which the mayor in in office
# for less than 5 years
data = df_placebo_2.loc[df_placebo_2["sum_years_as_mayor"]<5]

# Set the bandwidth (chosen to be the same as in the authors approach)
#bw = 15.71 # CCT
#bw = 15.71/2
#bw = 15.71*2
#bw = 17.22 # IK

# Get regression weights
data["weight"] = calculate_weights(df=df_placebo_2, bandwidth=bw)

# Replicate the placebo test using only these observations
sm.WLS(endog=data.loc[abs(data["margin_1"])<bw]["gewinn_norm"],
       exog=sm.add_constant(data.loc[abs(data["margin_1"])<bw][["female_mayor", "margin_1", "inter_1"]]),
       weights=data.loc[abs(data["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":data.loc[abs(data["margin_1"])<bw]["gkz"]}
            ).summary()
```

    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:12: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      if sys.path[0] == '':

WLS Regression Results

  Dep. Variable:	       gewinn_norm	     R-squared:         	    0.002

  Model:	                   WLS	         Adj. R-squared:    	   -0.002

  Method:	             Least Squares	    F-statistic:       	   0.3645

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	   0.779

  Time:	                 01:33:17	       Log-Likelihood:    	  -3072.2

  No. Observations:	         774	        AIC:               	    6152.

  Df Residuals:	             770	        BIC:               	    6171.

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	           -1.4878	     1.150	    -1.293	  0.196	    -3.742	     0.767

  female_mayor	     1.3984	     1.805	     0.775	  0.439	    -2.140	     4.936

  margin_1	        -0.0958	     0.126	    -0.759	  0.448	    -0.343	     0.151

  inter_1	         -0.0174	     0.195	    -0.089	  0.929	    -0.399	     0.364

  Omnibus:	       266.359	   Durbin-Watson:     	    1.989

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 3781.182

  Skew:	           1.144	    Prob(JB):          	     0.00

  Kurtosis:	      13.584	    Cond. No.          	     25.9

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

Summarizing the results of the placebo test, the following can be concluded:
First, the estimation results of a placebo test as it is presented in the article, particularly in table A.8 of the online appendix (see figure 8 below), can be replicated. In accordance to the argument in the article, the point estimate of this estimation shows to be relatively small in comparison to the main results. But more importantly, they do not show statistical significance and even reveal changes in signs for different bandwidths. This is seen as supporting evidence for robustness of the main results.

**Figure 8: Robustness Test I: Rank improvement of female candidates in previous council election**

Second, following above discussion of the term duration of mayors in Hesse and, consequentially, excluding all observations for which the mayor at time $t$ was in office for five or more years, does not lead to substantial differences in results. While in this specification there is no change in signs of the point estimate of the female mayor dummy, estimates still do not show statistical significance.

##### 3.2.2.2 Scaling of the Outcome Variable

In the second robustness test, the authors test whether the results of their analysis are sensitive regarding changes in the scaling of the outcome variable, i.e. the rank improvements of council candidates. As illustrated in section 2.2 of this notebook, the authors use normalized rank improvements in order to facilitate interpretability of the results as well comparability of changes in rank for different council sizes. Assessing robustness with regard to this scaling, alternative specifications of the regression model are presented using (a) raw rank improvements and (b) a dummy variable that takes value 1 if a candidate experienced a strictly positive rank improvement. Estimations for both specifications will be replicated in succeeding cells.

```python
# (a) raw rank improvements instead of normalized rank improvements as endogenous variable
# Set the bandwidth (taken from the paper)
bw = 19.31

# Get regression weights
rdd_data["weight"] = calculate_weights(df=rdd_data, bandwidth=bw)

# Run regression for approach (1): normalized rank improvement of female candidates on gender of mayor
sm.WLS(endog=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn"],
       exog=sm.add_constant(rdd_data.loc[abs(rdd_data["margin_1"])<bw][[
           "female_mayor",
           "margin_1",
           "inter_1"
       ]]),
       weights=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gkz"]}
            ).summary()
```

    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:6: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

WLS Regression Results

  Dep. Variable:	         gewinn	        R-squared:         	    0.022

  Model:	                   WLS	         Adj. R-squared:    	    0.021

  Method:	             Least Squares	    F-statistic:       	    3.790

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	  0.0154

  Time:	                 01:33:17	       Log-Likelihood:    	  -8870.9

  No. Observations:	        2842	        AIC:               	 1.775e+04

  Df Residuals:	            2838	        BIC:               	 1.777e+04

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	           -0.4034	     0.212	    -1.907	  0.056	    -0.818	     0.011

  female_mayor	     2.1297	     0.633	     3.365	  0.001	     0.889	     3.370

  margin_1	        -0.0343	     0.029	    -1.196	  0.232	    -0.090	     0.022

  inter_1	         -0.0669	     0.052	    -1.285	  0.199	    -0.169	     0.035

  Omnibus:	       974.904	   Durbin-Watson:     	    2.016

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 18644.289

  Skew:	           1.136	    Prob(JB):          	     0.00

  Kurtosis:	      15.340	    Cond. No.          	     40.3

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

```python
# (b) rank improvement dummy instead of normalized rank improvement as endogenous variable
# Set the bandwidth (taken from the paper)
bw = 18.11

# Get regression weights
rdd_data["weight"] = calculate_weights(df=rdd_data, bandwidth=bw)

# Run regression for approach (1): normalized rank improvement of female candidates on gender of mayor
sm.WLS(endog=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gewinn_dummy"],
       exog=sm.add_constant(rdd_data.loc[abs(rdd_data["margin_1"])<bw][[
           "female_mayor",
           "margin_1",
           "inter_1"
       ]]),
       weights=rdd_data.loc[abs(rdd_data["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":rdd_data.loc[abs(rdd_data["margin_1"])<bw]["gkz"]}
            ).summary()
```

    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:6: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

WLS Regression Results

  Dep. Variable:	      gewinn_dummy	     R-squared:         	    0.022

  Model:	                   WLS	         Adj. R-squared:    	    0.021

  Method:	             Least Squares	    F-statistic:       	    2.847

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	  0.0464

  Time:	                 01:33:17	       Log-Likelihood:    	  -2128.9

  No. Observations:	        2669	        AIC:               	    4266.

  Df Residuals:	            2665	        BIC:               	    4289.

  Df Model:	                   3

  Covariance Type:	       cluster

        	          coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	            0.3146	     0.028	    11.092	  0.000	     0.259	     0.370

  female_mayor	     0.2153	     0.075	     2.888	  0.004	     0.069	     0.362

  margin_1	        -0.0034	     0.004	    -0.908	  0.364	    -0.011	     0.004

  inter_1	         -0.0059	     0.006	    -0.963	  0.335	    -0.018	     0.006

  Omnibus:	       14966.361	   Durbin-Watson:     	    2.007

  Prob(Omnibus):	   0.000	     Jarque-Bera (JB):  	  325.586

  Skew:	            0.355	     Prob(JB):          	 1.99e-71

  Kurtosis:	        1.444	     Cond. No.          	     39.7

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

Comparing the results of above analysis to the results presented in the article (figure A.10 of the online appendix, shown in figure 9 below), no differences in results become apparent. The replication of this test for robustness of the main results with regard to scaling of the outcome variable was successful.

**Figure 9: Robustness Test II: Alternative scalings of rank improvement**

### 3.3 Internal Validity of the RD Design
Establishing internal validity is a prerequisite of the regression discontinuity design to be able to identify treatment effects in the same way a randomized trial does (Jacob et al. 2012). Therefore, it is crucial to rule out a non-random distribution of observations around the cutoff value of the treatment variable. In the context of the replicated article this means that municipalities around the cutoff value in the margin of victory of the mayor must not systematically differ in their characteristics. In other words, we need to rule out other drivers and channels through which a correlation between the rating variable (i.e. the margin of victory) and the outcome (rank improvements) might arise.

#### 3.3.1 Pretreatment Municipality Characteristics
The first test of validity the authors present adresses whether the RD design truly achieves a local randomization around the cutoff. If this is the case, then both, municipalities that are just below the cutoff of MoV = 0 and those just above this threshold should show the same distribution of characteristics. This is investigated using a t-test for differences in means of these characteristics in the year before the mayor election. Subsequently, a regression analysis is used to test for a correlation of the municipalities characteristics prior the mayor election and the elected mayors' genders. If observations are truly randomized around the cutoff value, we should not see any correlation between these characteristics and the mayors' genders.

In a first step, we will have a look at the municipalities' characteristics one year before a mayor election and perform a t-test to explore whether there are differences between municipalities in which a male candidate won the mixed-gender election and municipalities in which a female won the mixed-gender mayor election. This comparison will be performed for all mixed-gender elections as well as for close those mixed-gender elections only (i.e., with a margin of victory below 10%).

```python
# t-test for equality of means of muni's characteristics

# Merge data on mayor elections with municipalities' characteristics in the year prior the mayor election
# only keep observations on mixed gender elections
df_pretreatment_characteristics = df_mayor_election_data.loc[df_mayor_election_data.rdd_sample == 1].copy()

# merge with muni's characteristics in previous year
# comment out -1 in following line to get the same results the authors report.
df_pretreatment_characteristics["char_year"] = df_pretreatment_characteristics.jahr -1
df_pretreatment_characteristics = df_pretreatment_characteristics.merge(right=df_municipality_characteristics,
                                      how="left",
                                      left_on=["gkz", "char_year"],
                                      right_on=["gkz", "jahr"],

)
# We want to perform t-tests twice: for all mixed-gender elections and only "close" ones with MoV < 10 %
bandwidths = [100, 10]

# get results from the function in the auxiliary file
rslt_dict = ttest_mean_characteristics(df=df_pretreatment_characteristics, bw=bandwidths)

for k in rslt_dict.keys():
    print("For a margin of victory of " + str(k) + " or less :")
    display(rslt_dict[k])
```

    For a margin of victory of 100 or less :

      female_mayor
      male_mayor
      Diff.
      Obs.
      t_test_p

      log_bevoelkerung
      9.383204
      9.211695
      0.171510
      268
      0.159

      log_flaeche
      3.631587
      3.611326
      0.020261
      268
      0.840

      log_debt_pc
      -0.376616
      -0.543338
      0.166723
      268
      0.163

      log_tottaxrev_pc
      -0.389292
      -0.458939
      0.069647
      268
      0.186

      log_tot_beschaeft_pc
      -1.623035
      -1.548890
      -0.074145
      268
      0.330

      log_female_share_totbesch
      -0.832952
      -0.850199
      0.017247
      268
      0.549

      log_gemeinde_beschaef_pc
      -5.129807
      -5.160559
      0.030752
      268
      0.558

      log_female_sh_gem_besch
      -1.088507
      -1.148531
      0.060024
      264
      0.226

      log_prod_share_tot
      -1.116977
      -1.042058
      -0.074919
      268
      0.269

      log_female_share_prod
      -1.498887
      -1.467056
      -0.031831
      268
      0.449

    For a margin of victory of 10 or less :

      female_mayor
      male_mayor
      Diff.
      Obs.
      t_test_p

      log_bevoelkerung
      9.818720
      9.222251
      0.596469
      55
      0.056

      log_flaeche
      3.972175
      3.771001
      0.201174
      55
      0.311

      log_debt_pc
      -0.329899
      -0.291191
      -0.038708
      55
      0.882

      log_tottaxrev_pc
      -0.252976
      -0.356741
      0.103766
      55
      0.386

      log_tot_beschaeft_pc
      -1.330126
      -1.505435
      0.175308
      55
      0.261

      log_female_share_totbesch
      -0.892789
      -0.880949
      -0.011841
      55
      0.842

      log_gemeinde_beschaef_pc
      -4.922467
      -5.111784
      0.189317
      55
      0.219

      log_female_sh_gem_besch
      -1.058962
      -1.097358
      0.038396
      55
      0.693

      log_prod_share_tot
      -1.005072
      -0.963759
      -0.041313
      55
      0.744

      log_female_share_prod
      -1.542579
      -1.479899
      -0.062680
      55
      0.546

In comparison to the results of this analysis which are presented in table A4 by the authors (see figure 10 below), small differences can be seen. It is possible to replicate the results presented by the authors if, instead of considering the municipalities' characteristics of the *year preceding* the mayor election, one considers the characteristics of the *same year* as the mayor election. The results shown in this notebook, however, are calculated in accordance to the intuition discussed earlier: We want to find out, whether the RD design truly results in a local randomization, hence the municipalities closely around the cutoff must not significantly differ in characteristics that might have an impact on the outcome of a mixed gender mayor election.

Considering municipalities' characteristics of the year preceding the election will result in slightly different results than the ones presented by the authors. The authors argue, that when considering
>all mixed-gender races, the share of women in local public employment \[row log_female_sh_gem_besch\] is 8 percent higher, while in the manufacturing sector \[row log_female_share_prod\] it is 8 percent lower in municipalities with female mayors. For close mixed-gender elections, we find only one significant difference: municipalities with female mayors have larger populations \[row log_bevoelkerung\] than municipalities with male mayors. Yet, the effect is only barely significant and may be explained by the highly skewed distribution of city sizes.

This replication is able to confirm these results with regard to the close mixed-gender elections. For all mixed-gender elections, however, no significant differences can be found comparing characteristics for one year before the election. Results of this test for differences in means show to be quite sensitive with respect to small changes in the year for which characteristics are observed. Particularly, estimations including all mixed-gender mayor elections change drastically (i.e. show significance for different characteristics) for small changes in the year for which these characteristics are observed. This limits robustness of these results, especially since one should not expect a characteristic like, e.g., the share of women in the manufacturing sector to change very rapidly from one year to the next.

However, when assessing whether the local randomization around the cutoff truly is achieved, differences in characteristics of municipalities with close mixed-gender elections should be investigated in greater detail. Thus, the significant difference in population sizes of municipalities closely on either side of the cutoff really is what should be concerning when evaluating the internal validity of the RD design. Additionally, this difference shows to be robust with regard to changes in the year that is observed. Nevertheless, the authors argue that:
>"Yet, the effect is only barely significant and may be explained by the highly skewed distribution of city sizes."

Overall, mixed results can be drawn from this analysis. While the authors argue that differences are rather small and might arise from a skewed distribution, it cannot be precluded that differences in characteristics (i.e. population sizes) have an impact on the distribution around the cutoff. This, particularly, holds for municipalities closely around the cutoff value. In case population size truly impacts the rating of municipalities around the threshold, the local randomization cannot be held on to. In consequence the RD design is likely to yield biased estimates for the causal impact of the treatment (Lee 2008). For this reason, I present further investigations on this aspect of local randomization in section 4 of this notebook, succeeding the replication of the article.

**Figure 10: Validity test Ia: Differences in municipalitiy characteristics with female and male mayors**

Subsequently, the authors analyze whether differences in municipalities are able to explain a discontinuity in rank improvements of female council candidates. This is done in two consecutive steps:
1. Municipalities' characteristics are used to predict normalized rank improvements of council candidates.
→ See whether municipalities' characteristics have explanatory power on rank improvements.
2. These prediced rank improvements are used as an endogenous variable in a RDD regression.
→ Can municipalities' characteristics explain a discontinuity in rank improvements?

Both these steps are replicated in the following cells.

First, municipalities' characteristics are used to predict normalized rank improvement. The calculations in the article are resembled exactly by including all observations (*bw = 100*). However, it might by more relevant to check whether rank improvements can be predicted for municipalities in which the margin of victory is close to the cutoff value for two reasons:

1. We want to preclude that differences in characteristics of municipalities lead to a non-random local distribution of municipalities around the cutoff.

2. We say earlier, that differences in municipalities' characteristics show more significance for close mixed-gender elections (i.e., those that end up closely to the cutoff) than for all mixed-gender elections.

In contrast to the analysis presented in the article, in particular table A5 of the online appendix, the following estimation, thus, does not include all mixed-gender elections but focusses of those with an absolute margin of victory (MoV) smaller then 10.

```python
# Define bandwidth of data around the cutoff value (measured in absolute values)
bw=10

# define working df that does not contain any missing values and only observations within given bw
df_predicted_rank_improvements = rdd_data.loc[abs(rdd_data["margin_1"])<bw].dropna(subset=["margin_1",
                                                          "gewinn_norm",
                                                          "log_bevoelkerung",
                                                          "log_flaeche",
                                                          "log_debt_pc",
                                                          "log_tottaxrev_pc",
                                                          "log_gemeinde_beschaef_pc",
                                                          "log_female_sh_gem_besch",
                                                          "log_tot_beschaeft_pc",
                                                          "log_female_share_totbesch",
                                                          "log_prod_share_tot",
                                                          "log_female_share_prod"
                                                         ]
                                                )

# Run regression of rank improvements on municipalities' characteristics
muni_characteristics = sm.OLS(endog=df_predicted_rank_improvements["gewinn_norm"],
       exog=df_predicted_rank_improvements[["log_bevoelkerung",
                      "log_flaeche",
                      "log_debt_pc",
                      "log_tottaxrev_pc",
                      "log_gemeinde_beschaef_pc",
                      "log_female_sh_gem_besch",
                      "log_tot_beschaeft_pc",
                      "log_female_share_totbesch",
                      "log_prod_share_tot",
                      "log_female_share_prod"
                     ]]
      ).fit()

# Add the predicted rank improvement to the dataframe as it is needed in subceeding steps
df_predicted_rank_improvements["pred_rank_improvement"] = muni_characteristics.predict()

# Show regression summary
muni_characteristics.summary()
```

OLS Regression Results

  Dep. Variable:	       gewinn_norm	     R-squared:         	    0.022

  Model:	                   OLS	         Adj. R-squared:    	    0.017

  Method:	             Least Squares	    F-statistic:       	    4.017

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	 1.83e-05

  Time:	                 01:33:18	       Log-Likelihood:    	  -6735.1

  No. Observations:	        1780	        AIC:               	 1.349e+04

  Df Residuals:	            1770	        BIC:               	 1.355e+04

  Df Model:	                  10

  Covariance Type:	      nonrobust

              	                 coef	     std err	      t	      P>|t|	  [0.025	    0.975]

  log_bevoelkerung	              0.6205	     0.326	     1.902	  0.057	    -0.019	     1.260

  log_flaeche	                  -0.0003	     0.565	    -0.000	  1.000	    -1.109	     1.108

  log_debt_pc	                  -0.2981	     0.362	    -0.824	  0.410	    -1.008	     0.412

  log_tottaxrev_pc	             -1.9253	     1.176	    -1.637	  0.102	    -4.233	     0.382

  log_gemeinde_beschaef_pc	      1.5837	     0.583	     2.717	  0.007	     0.440	     2.727

  log_female_sh_gem_besch	       0.1834	     1.004	     0.183	  0.855	    -1.785	     2.152

  log_tot_beschaeft_pc	         -0.3582	     0.919	    -0.390	  0.697	    -2.160	     1.443

  log_female_share_totbesch	     2.6888	     2.627	     1.023	  0.306	    -2.464	     7.842

  log_prod_share_tot	           -1.4404	     0.934	    -1.543	  0.123	    -3.272	     0.391

  log_female_share_prod	        -1.2761	     1.098	    -1.162	  0.245	    -3.429	     0.877

  Omnibus:	       543.706	   Durbin-Watson:     	    2.094

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 4193.135

  Skew:	           1.215	    Prob(JB):          	     0.00

  Kurtosis:	      10.116	    Cond. No.          	     144.

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Two characteristics of the municipalities reveal to be significantly correlated with the rank improvement of a female candidate: Population size of the municipality (10% level) and per capita government employees (1% level). In addition, the regressor tax revenues per capita just barely misses to 10% significance threshold.

While the population size appears to be significantly positive correlated with rank improvement, the effect is quite small and does not seem to be of high economic significance: An increase of 1 % in population is associated with an increase in rank improvement of a female council candidate of approximately 0.62/100 normalized ranks. For the median size of a council (31 seats) this corresponds to 0.192 ranks.
Similarly, an increase in government employees is associated with an positive rank improvement of a female council candidate of approximately 0.490 ranks for the median council size.

In the second step, the authors use the prediction for rank improvements from above OLS model and test whether a discontinuity around the cutoff value of a margin of victory for a female mayor can be determined.

```python
# Use predicted values from above regression as endogenous variable in a regresion of female mayor on
# rank improvements (main model).

# Keep only 1 observation for each council election, since muni's characteristics dont vary within that
df_predicted_rank_improvements.drop_duplicates(subset=["gkz", "pred_rank_improvement"], inplace=True)

# Set the bandwidth (taken from the paper)
bw = 18.81

# Get regression weights
df_predicted_rank_improvements["weight"] = calculate_weights(df=df_predicted_rank_improvements, bandwidth=bw)

# Run regression for predicted normalized rank improvement of female candidates on gender of mayor
sm.WLS(endog=df_predicted_rank_improvements.loc[
    abs(df_predicted_rank_improvements["margin_1"])<bw]["pred_rank_improvement"
        ],
       exog=sm.add_constant(df_predicted_rank_improvements.loc[abs(df_predicted_rank_improvements["margin_1"])<bw][[
           "female_mayor", "margin_1", "inter_1"
       ]]),
       weights=df_predicted_rank_improvements.loc[abs(df_predicted_rank_improvements["margin_1"])<bw]["weight"],
      ).fit().summary()
```

WLS Regression Results

  Dep. Variable:	    pred_rank_improvement	   R-squared:         	    0.267

  Model:	                     WLS	            Adj. R-squared:    	    0.213

  Method:	               Least Squares	       F-statistic:       	    4.979

  Date:	               Thu, 01 Aug 2019	      Prob (F-statistic):	  0.00489

  Time:	                   01:33:18	          Log-Likelihood:    	  -70.532

  No. Observations:	            45	           AIC:               	    149.1

  Df Residuals:	                41	           BIC:               	    156.3

  Df Model:	                     3

  Covariance Type:	        nonrobust

        	          coef	     std err	      t	      P>|t|	  [0.025	    0.975]

  const	           -1.3275	     0.495	    -2.684	  0.010	    -2.326	    -0.329

  female_mayor	     2.6348	     0.783	     3.366	  0.002	     1.054	     4.216

  margin_1	        -0.1746	     0.093	    -1.887	  0.066	    -0.361	     0.012

  inter_1	          0.0414	     0.141	     0.293	  0.771	    -0.244	     0.327

  Omnibus:	        0.923	   Durbin-Watson:     	    1.260

  Prob(Omnibus):	  0.630	   Jarque-Bera (JB):  	    0.831

  Skew:	           0.014	   Prob(JB):          	    0.660

  Kurtosis:	       2.335	   Cond. No.          	     29.4

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

At this point, noticeable differences in results arise between the article and this replication. As seen in figure 11 below, the authors do not find a statistically significant estimate for the *female_mayor* dummy. However, the specification presented above does indicate a significant discontinuity in predicted normalized rank improvements around the cutoff at the 1% significance level. Indeed, the point estimate for the *female_mayor* dummy results to be approximately 2.63, which translates to circa 0.82 ranks for the median council size. To illustrate the scale of this effect: This amounts to approximately 71% of the size of the estimated effect for the main model (see section 2.2.1: Regression Results).

**Figure 11: Validity test Ib: Discontinuity in predicted rank improvements based on municipality characteristics**

Summarizing, the presented results differ from those presented in the article by changing the bandwidth of data included. While the authors find no significant discontinuity and, thus, do not reject a successful local randomization by the RD design, the results presented in this notebook cannot support this conclusion. In contrast to the conclusions drawn in the article, this analysis does not preclude a non-random distribution of the rating variable around the cutoff value. Indeed, these results indicate that municipalities' charateristics for the *year before* the close mixed-gender election happened (i.e. *pretreatment*) are associated with the rank improvements of a female council candidate.

#### 3.3.2 Discontinuity in Density

The next test with regard to internal validity that is presented by the authors is a test for a "discontinuity in density of the running variable at the threshold". That is, if there is a discontinuity in margins of victory that are closely around the cutoff value of 0. The result of this test can be seen in figure 12 below (figure A.2 in the article's online appendix). It is little surprising that a discontinuity cannot be found. Indeed, it is highly implausible that a council candidate can choose into treatment by raising the MoV of a mayor candidate to be just above the threshold of 0.

**Figure 12: Validity test IIa: McCrary density plot**

In a related validity check, the authors test whether men and women are equally likely to win a mixed-gender mayor election. Particularly, if the likelihood of a victory is equal in close mixed-gender elections. The results as they are presented by the authors in table A.6 of the online appendix can be seen in figure 13 below.

**Figure 13: Validity test IIb: Mixed-gender mayor elections and female victories**

```python
# Calculate the a priori probabilities of winning a mixed-gender election
# as the share of elections they where actually won by each gender.
rslt_dict = {}
bandwidths = [100, 25, 10]

# Loop over different bandwiths of data to consider
for bw in bandwidths:
    # Select data
    data = df_mayor_election_data.loc[
        (df_mayor_election_data["rdd_sample"]==1) & (abs(df_mayor_election_data["margin_1"])<=bw)
    ]

    # Write mean, difference in means, N and p-value of the t-test into a frame
    container = pd.DataFrame(index=[1])
    container["Mean female win"] = (data["female_mayor"].sum() / data.female_mayor.count()).round(3)
    container["Diff."] = (2 * container["Mean female win"] - 1).round(3)
    container["Obs."] = data["female_mayor"].count()
    satistic, p_value = ttest_ind(data["female_mayor"], data["male_mayor"])
    container["t_test_p"] = p_value.round(3)

    # return results in a dictionary
    rslt_dict[bw] = container

# Print resulting dict in an understanable way
for k in rslt_dict.keys():
    print("t-Test for differences in means for a bandwidth of {}".format(k))
    display(rslt_dict[k])
```

    t-Test for differences in means for a bandwidth of 100

      Mean female win
      Diff.
      Obs.
      t_test_p

      1
      0.313
      -0.374
      268
      0.0

    t-Test for differences in means for a bandwidth of 25

      Mean female win
      Diff.
      Obs.
      t_test_p

      1
      0.405
      -0.19
      126
      0.002

    t-Test for differences in means for a bandwidth of 10

      Mean female win
      Diff.
      Obs.
      t_test_p

      1
      0.527
      0.054
      55
      0.571

The results of this validity test can successfully be replicated. Just like presented by the authors, there is significant differences in the probability of a woman to win the mayoral election for large bandwidths, i.e. when not only close mixed-gender elections are considered. The significance in this difference, however, cannot be seen for mixed-gender elections with a MoV of 10% or lower. Thus, there is no reason to believe that either gender has a higher chance of winning close elections. This supports the hypotheses of a local randomization around the cutoff.

#### 3.3.3. Confoundness with Mayor Ideology
The final concern the authors adress in the regard of internal validity are confounding effects due the political identity of mayors and council candidates. This might arise if males and females differ in their party affiliation. For example, female politicians might be more likely to be affiliated with left-wing parties. In this case, the success of a female council candidate in a municipality with a female mayor might be driven by their similar political affiliation and trends in general popularity of political ideologies, rather than a decrease in anti-female voters bias.

In the article, this is approached by testing for differences in ideology of female and male mayors. Results of this test are provided in table A.7 of the online appendix and can be found in figure 14 below. Again, the authors investigate both, the whole sample of mixed-gender mayor elections and a subsample of those with a MoV smaller 10%. Overall, differences in the ideology of mayors in mixed-gender elections do not show statistical significance. Hence, it is implausible to argue that election outcomes of council candidates are related to these differences.

**Figure 14: Validity test III: Differences in ideology of female and male mayors**

```python
# Run a t-test for differences in the shares of party affiliation for male and female
# mayors that won a mixed-gender election

# Set the list of bandwiths for which these differences should be calculated
bandwidths = [100, 25, 10]

# get results from the function in the auxiliary file
rslt_dict = party_affiliation(df=df_mayor_election_data, bw=bandwidths)

# Print resulting dict in an understanable way
for k in rslt_dict.keys():
    print("t-Test for differences in shares of mayors that are"+
          "affilited with each party for a bandwidth of {}".format(k)
         )
    display(rslt_dict[k])
```

    t-Test for differences in shares of mayors that areaffilited with each party for a bandwidth of 100

      female_mayor_shares
      male_mayor_shares
      p_value
      difference

      cdu
      0.31
      0.315
      0.926
      -0.005

      spd
      0.44
      0.386
      0.400
      0.054

      other_party
      0.25
      0.299
      0.412
      -0.049

    t-Test for differences in shares of mayors that areaffilited with each party for a bandwidth of 25

      female_mayor_shares
      male_mayor_shares
      p_value
      difference

      cdu
      0.333
      0.373
      0.649
      -0.040

      spd
      0.392
      0.293
      0.252
      0.099

      other_party
      0.275
      0.333
      0.487
      -0.058

    t-Test for differences in shares of mayors that areaffilited with each party for a bandwidth of 10

      female_mayor_shares
      male_mayor_shares
      p_value
      difference

      cdu
      0.448
      0.308
      0.293
      0.140

      spd
      0.276
      0.308
      0.800
      -0.032

      other_party
      0.276
      0.385
      0.400
      -0.109

First of all, the results regarding differences in party affiliation of mayors of different gender as presented in the article can be replicated. From these results it can be seen that independent of the bandwidth selection around the cutoff value, mayors of different sexes reveal quite little differences in their party affiliation. In addition, none of these differences prove to be statistically significant.

Building on this result, one can argue that differences in political ideology between male and female politicians are not driving the observed association of mayors that won a close mixed-gender election with rank improvements of council candidates of the same sex. Thus, a confoundedness of mayors' and council candidates' ideologies can be ruled out as an explanation of the main results presented in section 2.2.1.

## 4. Independent Contribution: On Internal Validity of the RD Design
Validity of the RD design as it is presented in the replicated article is discussed in section 3 of this notebook. In this context, I argue that significant differences in population sizes of municipalities closely below and closely above the threshold value of MoV = 0% might be a reason to question whether the RD design truly achieves a local randomization. It is shown that means of population sizes significantly differ between both sides of the threshold.

Furthermore, using municipalitie's characteristics to predict rank improvements of council candidates (section 3.3.1) revealed a significant positive correlation between population size and rank improvements. This resulted from an estimation that only included observations that were within a 10 percentage point range around the cutoff value of MoV.

A local randomization with regard to population sizes does not seem very convincing. Therefore, an alternative estimation model for the correlation between a female mayor and rank improvements of female council candidates is presented in the following which includes population size as a predictor. The model follows equation (4) which is equivalent to equation (3) (main model) appended by the population of the municipality in logs as well as an interaction term between the female mayor dummy and population in logs.

\begin{align}
    normalized\_rank\_improvement_i = \beta_0 + \beta_1 D_{f\_mayor, i} + \beta_2 MoV_i + \beta_3 D_{f\_mayor, i} * MoV_i  + \\ \beta_4 log(population_i) + \beta_5 D_{f\_mayor, i} * log(population_i) \tag{4}
\end{align}

The estimation of this model follows the same WLS method as the estimation of the baseline results presented in section 3.2. A summary of the results of this regression can be seen below.

```python
# Add intercept of population size and MoV to regression data
df_population_regression = rdd_data.copy()
df_population_regression["inter_margin_pop"] = df_population_regression["female_mayor"] * df_population_regression["log_bevoelkerung"]

# Set the bandwidth
#bw = 20
#bw = 15
#bw = 10

# Get regression weights
df_population_regression["weight"] = calculate_weights(df=df_population_regression, bandwidth=bw)

# Run regression for approach (1): normalized rank improvement of female candidates on gender of mayor
sm.WLS(endog=df_population_regression.loc[abs(df_population_regression["margin_1"])<bw]["gewinn_norm"],
       exog=sm.add_constant(df_population_regression.loc[abs(df_population_regression["margin_1"])<bw][
           ["female_mayor", "margin_1", "inter_1", "log_bevoelkerung", "inter_margin_pop"]
       ]),
       weights=df_population_regression.loc[abs(df_population_regression["margin_1"])<bw]["weight"],
      ).fit(cov_type="cluster",
             cov_kwds={"groups":df_population_regression.loc[abs(df_population_regression["margin_1"])<bw]["gkz"]}
            ).summary()
```

WLS Regression Results

  Dep. Variable:	       gewinn_norm	     R-squared:         	    0.018

  Model:	                   WLS	         Adj. R-squared:    	    0.015

  Method:	             Least Squares	    F-statistic:       	    16.10

  Date:	             Thu, 01 Aug 2019	   Prob (F-statistic):	 2.49e-08

  Time:	                 01:33:18	       Log-Likelihood:    	  -6966.8

  No. Observations:	        1784	        AIC:               	 1.395e+04

  Df Residuals:	            1778	        BIC:               	 1.398e+04

  Df Model:	                   5

  Covariance Type:	       cluster

          	            coef	     std err	      z	      P>|z|	  [0.025	    0.975]

  const	               -5.8585	     4.165	    -1.406	  0.160	   -14.022	     2.305

  female_mayor	         2.2883	     4.668	     0.490	  0.624	    -6.861	    11.438

  margin_1	            -0.1434	     0.124	    -1.161	  0.246	    -0.386	     0.099

  inter_1	             -0.0377	     0.207	    -0.182	  0.855	    -0.443	     0.368

  log_bevoelkerung	     0.4705	     0.414	     1.137	  0.256	    -0.341	     1.282

  inter_margin_pop	     0.0820	     0.442	     0.186	  0.853	    -0.784	     0.948

  Omnibus:	       694.757	   Durbin-Watson:     	    2.110

  Prob(Omnibus):	  0.000	    Jarque-Bera (JB):  	 8850.060

  Skew:	           1.461	    Prob(JB):          	     0.00

  Kurtosis:	      13.513	    Cond. No.          	     419.

Warnings:
[1] Standard Errors are robust tocluster correlation (cluster)

The estimation results of this model reveal noticeable differences to the results presented for the baseline model. First, the estimation for the female mayor dummy is not significant in this estimation. Hence, the discontinuity in rank improvements at the cutoff is not significant for this estimation. Second, the only predictor that is significantly correlated with the outcome is the population size of the municipality. Third, the adjusted R-Squared is increased by approximately 50% in comparison to the baseline model. Changes in the bandwidth result in changes in the adjusted R-squared. However, this 50% increase appears to mark a lower bound.

Since a python package for an optimal bandwidth selection that implements the method used in the article is not available, estimation results were calculated using an array of different bandwidths. This can be adjusted by modifying above cell. The currently chosen bandwidth of 15 is used since it fits in the range of different bandwidths that are presented by the authors for different estimations. Generally, optimal bandwidths throughout this article range from 15 to 20. These results are very little affected by changes in the bandwidth.

To summarize, a comparison of characteristics of municipalities that lie respectively just below or above the cutoff value indicates that a local randomization might not have been achieved. In particular, population size appears to have explanatory power on the election success of female council candidates. Including population size as a covariate in the estimation model results in a non-significant discontinuity while increasing the adjusted R-Squared. Finally, without a random assignment into treated and untreated groups around the cutoff, the internal validity of an RD design must be taken into question, hence causal inference looses credibility in the RD design (see Lee, 2008 for a discussion).

## 5. Conclusions
The replication of the baseline results of Baskaran & Hessami (2018) presented throughout this notebook yields exactly the same results as the authors present in their article. In addition to the results of the baseline model, I also (mostly successful) replicate the results presented on robustness tests as well as tests for internal validity of the regression discontinuity design. Furthermore, the scope of a mere replication is left at several points and additional analyses on the internal validity of the RD design are presented. The results of this work can be summarized as follows.

First, it was possible to replicate the baseline estimations. Using the data set as it is provided by the authors, a weighted linear regression yields the exact same results that are presented in section *IV Main Results* of the article.

Second, I was able to replicate the results of the tests for robustness of these baseline regression results, in particular a placebo test as well as a test for different scalings of the outcome variable. In the context of the placebo test, I additionally present results of an even stricter specification. This specification addresses a potential weakness of the placebo test implemented in the article regarding an overlap of the tenure of a mayor and the time lag chosen by the authors. However, the results of the placebo test are not affected by this.

Third, at least two of the three presented results of tests for the internal validity can be confirmed by this replication. That is, the results of the test for a discontinuity in density as well as for a confoundedness of council candidates with the mayor's ideology can be confirmed by this work.  Yet, the outcome of the replication regarding the pretreatment municipality characteristics needs to be carried out in more detail.

One (minor) difference between the test results presented in the article and the outcome of their replication is based on a difference in coding. For the intuition of a pretreatment analysis it is argued that characteristics of municipalities which are respectively just below or barely above the cutoff value of the rating variable should be compared for a time before the treatment is in place. That is, before a close mixed-gender election was won by either candidate. Hence, the results presented in this notebook stem from a comparison of characteristics in the year before the mayor election. In the article, however, differences are calculated for the same year as the mayor election.

The more important difference in results, however, can be found in the succeding analysis. Here, municipalities' characteristics are used to predict rank improvements of council candidates. While the authors perform this analysis for all municipalities with mixed-gender mayor elections, I argue that a more relevant insight would result by focusing on close mixed-gender elections, only. Contrary to the results presented by the authors, including only this smaller set of municipalities indeed results in significant estimates for some of the characteristics, including the municipalities' population size.

Subsequently, the resulting predicted rank improvements are tested for a discontinuity at the cutoff value of the rating variable. Again, in contrast to the results presented in the article the alternative specification presented in this notebook yields a significant estimate of relevant magnitude for this discontinuity. In particular, the main results indicate a discontinuity of approximately magnitude 3.7 while the point estimate for this discontinuity takes a value of circa 2.6 for the alternative specification.

Based on these results, I propose a modified specification of the original regression model which includes population size as an additional predictor. An estimation of this specification yields a positive and significant coefficient for population size, indicating a positive association of population size and the normalized rank improvements of female council candidates, even within a small bandwidth around the cutoff value of the rating variable. Additionally, this specification does not result in significant estimations for the effect of a female mayor.

The results of these regression analyses put a question mark on the internal validity of the RD design presented by the authors. However, further investigations on this particular aspect of the relationship between rank improvements of female council candidates and the population sizes of municipalities would be needed to take a final position on the relation between female mayors and success of female council candidates.

## References
**Baskaran, T., & Hessami, Z.** (2018) Does the Election of a Female Leader Clear the Way for More Women in Politics? *American Economic Journal: Economic Policy*, 10(3): 91-121

**Jacob, R., Zhu, P., Somers, M. A., & Bloom, H.** (2012). A Practical Guide to Regression Discontinuity. MDRC.

**Lee, D. S.** (2008). Randomized experiments from non-random selection in US House elections. *Journal of Econometrics*, 142(2), 675-697

```python

```