Skip to content

Commit 605bfcb

Browse files
committed
Complete data loading, add tests, bump version
1 parent bdb1bcc commit 605bfcb

File tree

5 files changed

+118
-11
lines changed

5 files changed

+118
-11
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "SynthControl"
22
uuid = "a73a6d50-3b99-11e9-2e1c-6f5007f3555d"
33
authors = ["Nils <nilshg@hotmail.com>"]
4-
version = "0.2.0"
4+
version = "0.2.1"
55

66
[deps]
77
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"

src/SynthControl.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import CSV
66
using Reexport
77
@reexport using TreatmentPanels
88

9-
export SynthControlModel, fit!, isfitted, load_brexit, load_germany, load_basque, load_smoking
9+
export SynthControlModel, fit!, isfitted
10+
export load_brexit, load_germany, load_basque, load_smoking
11+
export load_brexit_panel, load_germany_panel, load_basque_panel, load_smoking_panel
1012

1113
include("synthcontrolmodels.jl")
1214
include("plotrecipes.jl")

src/load_data.jl

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,127 @@
33
"""
44
load_brexit()
55
6-
Returns a `DataFrame` with quarterly GDP data on 30 OECD countries, borrowed from the
7-
analysis of the effect of Brexit on UK GDP undertaken by the [Centre for European Reform](
6+
Returns a `DataFrame` with quarterly GDP data on 30 OECD countries, borrowed from the analysis of
7+
the effect of Brexit on UK GDP undertaken by the [Centre for European Reform](
88
https://www.cer.eu/insights/cost-brexit-june-2019)
99
10-
The `TreatmentPanel` for Brexit should be specified as
11-
```
12-
TreatmentPanel("United Kingdom" => Date(2016, 7, 1), df;
13-
outcome = :realgdp, id_var = :country, t_var = :quarter)
14-
```
10+
With the Brexit referendum having taken place on 23 June 2016, the `TreatmentPanel` for Brexit
11+
should be specified as
12+
```
13+
TreatmentPanel(df, "United Kingdom" => Date(2016, 7, 1);
14+
outcome = :realgdp, id_var = :country, t_var = :quarter)
15+
```
1516
"""
1617
function load_brexit()
1718
CSV.read(joinpath(dirname(@__FILE__),"..","data","brexit.csv"), DataFrame; stringtype = String)
1819
end
1920

21+
"""
22+
load_brexit_panel()
23+
24+
Returns a `BalancedPanel` object based on the data set available through load_brexit(), with
25+
treatment assignment specified as `"United Kingdom" => Date(2016, 7, 1)`
26+
27+
"""
2028
function load_brexit_panel()
2129
df_brexit = load_brexit()
2230
BalancedPanel(df_brexit, "United Kingdom" => Date(2016, 7, 1);
2331
id_var = :country, t_var = :quarter, outcome_var = :realgdp)
2432
end
2533

34+
35+
"""
36+
load_germany()
37+
38+
Returns a `DataFrame` with annual observations of per-capita GDP and covariates between 1960 and
39+
2003. The data is used in Abadie, Diamond and Hainmueller (2015) to study the effect of German
40+
unification on per-capita GDP.
41+
42+
As German reunification occurred in 1990, the `TreatmentPanel` for use in synthetic control
43+
estimation should be specified as:
44+
45+
```
46+
TreatmentPanel(df, "West Germany" => 1990,
47+
id_var = "country", t_var = "year", outcome_var = "gdp")
48+
```
49+
"""
2650
function load_germany()
2751
CSV.read(joinpath(dirname(@__FILE__),"..","data","germany.csv"), DataFrame; stringtype = String)
2852
end
2953

54+
"""
55+
load_germany_panel()
56+
57+
Returns a `BalancedPanel` object based on the data available from `load_germany()`, with
58+
treatment assignment specified as `"West Germany" => 1990`
59+
"""
3060
function load_germany_panel()
3161
df_germany = load_germany()
3262
BalancedPanel(df_germany, "West Germany" => 1990;
3363
id_var = "country", t_var = "year", outcome_var = "gdp")
3464
end
3565

66+
"""
67+
load_basque()
68+
69+
Returns a `DataFrame` with annual observations of per-capita GDP and covariates between 1955 and
70+
1997. The data is used in Abadie and Gardeazabal (2003) to study the effect of ETA terrorism
71+
on per-capita GDP in the Basque country.
72+
73+
To undertake analysis simliar to that in Abadie and Gardeazabal (2003), the `TreatmentPanel` for
74+
use in synthetic control estimation should be specified as:
75+
76+
```
77+
TreatmentPanel(df, "Basque Country (Pais Vasco)" => 1970,
78+
id_var = "regionname", t_var = "year", outcome_var = "gdpcap")
79+
```
80+
"""
3681
function load_basque()
3782
CSV.read(joinpath(dirname(@__FILE__),"..","data","basque.csv"), DataFrame;
3883
stringtype = String, missingstring = "NA")
3984
end
4085

86+
"""
87+
load_basque_panel()
88+
89+
Returns a `BalancedPanel` object based on the data available from `load_basque()`, with
90+
treatment assignment specified as `"Basque Country (Pais Vasco)" => 1970`
91+
"""
4192
function load_basque_panel()
4293
df_basque = load_basque()
4394
BalancedPanel(df_basque, "Basque Country (Pais Vasco)" => 1970;
4495
id_var = "regionname", t_var = "year", outcome_var = "gdpcap")
4596
end
4697

98+
"""
99+
load_smoking()
100+
101+
Returns a `DataFrame` with annual observations of cigarette sales and covariates for 39 US
102+
states between 1970 and 2000. The data is used in Abadie, Diamond and Hainmueller (2010) to
103+
study the effect of Proposition 99 on cigarette sales in California
104+
105+
To undertake analysis simliar to that in Abadie, Diamond and Hainmueller (2010), the
106+
`TreatmentPanel` for use in synthetic control estimation should be specified as:
107+
108+
```
109+
TreatmentPanel(df, 3 => 1989,
110+
id_var = "state", t_var = "year", outcome_var = "cigsale")
111+
```
112+
"""
47113
function load_smoking()
48-
CSV.read(joinpath(dirname(@__FILE__),"..","data","smoking.csv"), DataFrame;
114+
df_smoking = CSV.read(joinpath(dirname(@__FILE__),"..","data","smoking.csv"), DataFrame;
49115
stringtype = String, missingstring = "NA")
116+
select!(df_smoking, Not(:Column1))
50117
end
118+
119+
"""
120+
load_smoking_panel()
121+
122+
Returns a `BalancedPanel` object based on the data available from `load_smoking()`, with
123+
treatment assignment specified as `3 => 1989`
124+
"""
125+
function load_smoking_panel()
126+
df_smoking = load_smoking()
127+
BalancedPanel(df_smoking, 3 => 1989;
128+
id_var = :state, t_var = :year, outcome_var = :cigsale)
129+
end

src/synthcontrolmodels.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ function fit!(s::SynthControlModel; placebo_test = false)
8686

8787
# Objective function
8888
# Hat tip to Mathieu Tanneau who suggested switching to a quadratic formulation
89-
obj(w) = dot(y₁₀ .- vec(w'*yⱼ₀), y₁₀ .- vec(w'*yⱼ₀)) + 1e6*(1.0 - sum(w))^2
89+
# !# Check why yⱼ₀ transpose is needed - is this consistent with mathematical formulation of
90+
# model? Appears so, the notation for y₁₀ based on the outcome matrix and x₀ based on a vector
91+
# of covariates are incompatible
92+
obj(w) = (y₁₀ .- yⱼ₀'w)'*(y₁₀ .- yⱼ₀'w) + 1e6(1.0 -sum(w))^2
9093

9194
# Initial condition and bounds
9295
initial = [1/J for _ in 1:J]

test/runtests.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,26 @@ using SynthControl, TreatmentPanels, DataFrames, Dates
2727
@test isfitted(s)
2828

2929
end
30+
31+
32+
@testset "Data sets" begin
33+
34+
df = load_germany()
35+
@test only(df[df.country .== "USA" .&& df.year .== 1961, :gdp]) == 2929
36+
37+
bp = load_germany_panel()
38+
@test typeof(bp) <: BalancedPanel
39+
40+
df = load_basque()
41+
@test only(df[df.regionno .== 1 .&& df.year .== 1957, :gdpcap]) == 2.60361314875437
42+
43+
bp = load_basque_panel()
44+
@test typeof(bp) <: BalancedPanel
45+
46+
df = load_brexit()
47+
@test only(df[df.country .== "Australia" .&& df.quarter .== Date(2009, 1, 1), :realgdp]) == 1.04
48+
49+
bp = load_brexit_panel()
50+
@test typeof(bp) <: BalancedPanel
51+
52+
end

0 commit comments

Comments
 (0)