7) The Impact of Legalizing Prostitution on Crime

Vitor Kamada

E-mail: econometrics.methods@gmail.com

Last updated: 11-2-2020

In the Netherlands, there are legal prostitution zones that in Dutch is called tippelzones. Bisschop et al. (2017) reported that the opening of a tippelzone reduces sexual abuse and rape by about 30-40%.

Let’s open the dataset of Bisschop et al. (2017). Each row is a city in the Netherlands. The same city is observed between 1994–2011.

import numpy as np
import pandas as pd
pd.set_option('precision', 3)

# Data from Bisschop et al. (2017)
path = "https://github.com/causal-methods/Data/raw/master/" 
df = pd.read_stata(path + "CBSregist2015.dta")
df.head(5)
city year opening closing city1 logpopdens openingReg mayorCDA mayorCU mayorD66 ... simtheftpcN aggtheftpcN lnsimtheftN lnaggtheftN theftpcN lntheftN pordoffpcN pordviolpcN lnpordoffN lnpordviolN
0 Amsterdam 1994-01-01 0.0 0.0 1.0 8.381 0.0 0.0 0.0 0.0 ... 59.246 57.934 8.364 8.342 117.181 9.046 7.596 5.110 6.310 5.914
1 Amsterdam 1995-01-01 0.0 0.0 1.0 8.379 0.0 0.0 0.0 0.0 ... 50.815 43.823 8.208 8.060 94.637 8.830 7.061 4.361 6.234 5.753
2 Amsterdam 1996-01-01 1.0 0.0 1.0 8.373 0.0 0.0 0.0 0.0 ... 42.333 37.111 8.020 7.888 79.444 8.649 7.520 5.431 6.292 5.966
3 Amsterdam 1997-01-01 1.0 0.0 1.0 8.369 0.0 0.0 0.0 0.0 ... 46.843 32.860 8.117 7.762 79.704 8.648 6.852 4.195 6.194 5.704
4 Amsterdam 1998-01-01 1.0 0.0 1.0 8.373 0.0 0.0 0.0 0.0 ... 45.255 33.907 8.086 7.798 79.162 8.646 6.127 4.595 6.087 5.799

5 rows × 65 columns

Let’s break the cities into 3 groups. Big cities and medium cities had a tippelzone in at least one year, whereas the other cities in the sample hadn’t a tippelzone.

big_cities = ["Amsterdam", "Rotterdam", "Den Haag"]
medium_cities = ["Utrecht", "Nijmegen", "Groningen",
                 "Heerlen", "Eindhoven", "Arnhem"]

# Classify cities
def classify(var):
    if var in big_cities:
        return "Big Cities"
    elif var in medium_cities:
        return "Medium Cities"    
    else:   
        return "No tippelzone"

df['group'] = df["city"].apply(classify)

Below are the annual crime reports per 10,000 inhabitants. Overall, big cities have higher crime rates. The exception is a drug-related crime.

outcome = ['sexassaultpcN', 'rapepcN', 
	'drugspcN', 'maltreatpcN', 'weaponspcN']

df.groupby('group')[outcome].mean().T
group Big Cities Medium Cities No tippelzone
sexassaultpcN 0.775 0.626 0.664
rapepcN 1.032 0.846 0.691
drugspcN 14.921 15.599 12.779
maltreatpcN 21.259 18.665 17.864
weaponspcN 5.635 4.385 4.207

Tippelzones cities are more populated and densely populated than cities without tippelzones. Average household income (“inkhh”) measured in 1,000 euros is similar in the 3 groups. Tippelzones cities also have individuals with a higher level of education. The proportion of immigrants is higher in big cities (11.4%). The share of social insurance benefits (“insurWWAO_pc”) is similar to the 3 groups.

demographics = ['popul_100', 'pop_dens_100', 'popmale1565_100',
            'inkhh', 'educhpc', 'nondutchpc', 'insurWWAO_pc']

df.groupby('group')[demographics].mean().T  
group Big Cities Medium Cities No tippelzone
popul_100 5974.886 1724.191 1131.138
pop_dens_100 43.258 22.977 19.560
popmale1565_100 2101.446 617.019 392.255
inkhh 29.052 28.989 30.502
educhpc 0.300 0.317 0.245
nondutchpc 0.114 0.059 0.052
insurWWAO_pc 0.074 0.081 0.078

The Christian Union party has more mayors (31%) in cities without tippelzone. It is worth mentioning that this party opposes the opening of the tippelzone.

political_party = ['mayorSoc', 'mayorLib', 'mayorChr']
df.groupby('group')[political_party].mean().T  
group Big Cities Medium Cities No tippelzone
mayorSoc 0.481 0.556 0.410
mayorLib 0.259 0.324 0.278
mayorChr 0.259 0.120 0.312

The dataset is a balanced Panel Data. It is necessary to declare the indices in order: the unit of analysis and time unity.

df['year'] = pd.DatetimeIndex(df['year']).year
df['Dyear'] = pd.Categorical(df.year)

# Set Panel Data
# Set city as the unit of analysis
df25 = df.set_index(['city1', 'year'])

Let \(Y_{ct}\) be the crime in city \(c\) in year \(t\). Let \(D_{ct}\) = 1 if city \(c\) had an open tippelzone in year \(t\); and 0 otherwise. Let’s estimate the following model:

\[ln(Y_{ct})=\alpha_c+\rho D_{ct}+\beta X_{ct}+\gamma_t + \epsilon_{ct}\]

where \(\alpha_c\) is the city fixed effects, \(X_{ct}\) is the vector of control variables, \(\gamma_t\) is the year fixed effects, and \(\epsilon_{ct}\) the usual error term.

import statsmodels.formula.api as smf

Ys = ["lnsexassaultN", "lnrapeN", "lndrugsN",
      "lnweaponsN", "lnmaltreatN"]

base = "~ 1 + opening"
fe = "+ C(city) + C(Dyear)"

controls = ['logpopmale1565', 'logpopdens', 'inkhh', 
	'educhpc', 'nondutchpc', 'insurWWAO', 'mayorCDA',
  'mayorCU', 'mayorD66', 'mayorVVD']

Xs = ""
for var in controls:
    Xs = Xs + '+' + var

columns = []
for Y in Ys:
  result = smf.ols(Y + base + fe + Xs, df25).fit(cov_type='cluster',
                cov_kwds={'groups': df25['city']})
  columns.append(result)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5)
WARNING: Error parsing requirements for numpy: [Errno 2] No such file or directory: 'c:\\anaconda\\envs\\textbook\\lib\\site-packages\\numpy-1.19.2.dist-info\\METADATA'

Column 1 indicates that an open tippelzone decreases sexual abuse by 26% (\(e^{-0.302}-1\)). In the other columns, the coefficients of tippelzone are not statistically significant. It looks that legalizing prostitution decreases sexual abuse, but not other crimes as rape, assault, illegal weapon, and drug-related.

# Settings for a nice table
from stargazer.stargazer import Stargazer
stargazer = Stargazer(columns)

stargazer.title('The Impact of Tippelzone on Crime')

names = ['Sex Abuse', 'Rape', 'Drugs', 'Weapons', 'Assault']
stargazer.custom_columns(names, [1, 1, 1, 1, 1])

stargazer.covariate_order(['opening'])

stargazer.add_line('Covariates', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])

stargazer.add_line('City Fixed Effects', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])
stargazer.add_line('Year Fixed Effects', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])

stargazer
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
The Impact of Tippelzone on Crime
Sex AbuseRapeDrugsWeaponsAssault
(1)(2)(3)(4)(5)
opening-0.302***-0.042-0.057-0.074-0.017
(0.091)(0.060)(0.076)(0.093)(0.060)
CovariatesYesYesYesYesYes
City Fixed EffectsYesYesYesYesYes
Year Fixed EffectsYesYesYesYesYes
Observations450450450450450
R20.7270.7940.8990.9070.957
Adjusted R20.6920.7670.8860.8950.952
Residual Std. Error0.485 (df=397)0.449 (df=397)0.330 (df=397)0.289 (df=397)0.165 (df=397)
F Statistic26.328*** (df=52; 397)65.173*** (df=52; 397)45.273*** (df=52; 397)10.007*** (df=52; 397)252.545*** (df=52; 397)
Note: *p<0.1; **p<0.05; ***p<0.01
import math
math.exp(-0.302) - 1 
-0.2606619351104681

Exercises

1| In the introduction of the paper, Bisschop et al. (2017: 29) state: “Our study is one of the first to provide causal evidence for the connection between the regulation of prostitution and crime.” In the discussion section, Bisschop et al. (2017:44) state: “The opening of a tippelzone with or without a licensing system is correlated with a short-run decrease of 30-40 percent in sexual abuse and rape, and the results are robust to different specifications.” Why do Bisschop et al. (2017) use the word “causal” in the introduction and “correlated” in the discussion section? Do you consider the main results of Bisschop et al. (2017) as “causal” or “correlation”? Justify.

2| Bisschop et al. (2017: 29) state: “We perform several empirical tests to assess endogenous crime trends around the moment of opening a tippelzone.” Why do they do that? What is the logic of that? Are there or not endogenous crime trends? Justify and be specific in your answer.

3| Bisschop et al. (2017: 36) state: “… the time trend \(\mu_t\) is modeled using year fixed effects”. What are the other ways to model the time trend? Write different pieces of code to create time trends under different assumptions. Hint: Remember that this is a Panel Data. A proper code that works in Cross-Sectional Data will create the wrong variable in a Panel Data Structure.

4| Bisschop et al. (2017: 36) state: “We use a difference-in-difference specification to study the effect of the presence of a tippelzone on various types of crime.” What is the key assumption to deploy a difference-in-difference estimator?

5| Replicate the table “The Impact of Tippelzone on Crime” without Amsterdam, Rotterdam, and Den Haag. Additionally, replace the variable “opening” with the following four variables:

i) “everopenNoReg”: 1 if city \(c\) ever has open tippelzone in or before year \(t\) which opened without licensing, and 0 otherwise.

ii) “openingRegP”: 1 if city \(c\) has open tippelzone and introduced licensing ex-post in or before year \(t\), and 0 otherwise.

iii) “openingRegA”: 1 if city \(c\) ever has open tippelzone in or before year \(t\) which opened with licensing, and 0 otherwise.

iv) “closing”: 1 if city \(c\) closes tippelzone in or before year \(t\), and 0 otherwise.

Interpret the results.

Reference

Bisschop, Paul, Stephen Kastoryano, and Bas van der Klaauw. (2017). Street Prostitution Zones and Crime. American Economic Journal: Economic Policy, 9 (4): 28-63.