Skip to content

Commit 9bb0854

Browse files
committed
Subtree merge InteractionWeightedDIDs
Add lib/InteractionWeightedDIDs/ from JuliaDiffinDiffs/InteractionWeightedDIDs.jl@68e9207
1 parent 32395db commit 9bb0854

File tree

15 files changed

+2554
-0
lines changed

15 files changed

+2554
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: CI-latest
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
push:
7+
branches:
8+
- master
9+
tags: '*'
10+
jobs:
11+
test:
12+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
13+
env:
14+
JULIA_NUM_THREADS: 2
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
version:
20+
- 'nightly'
21+
os:
22+
- 'ubuntu-latest'
23+
- 'macos-latest'
24+
arch:
25+
- 'x64'
26+
steps:
27+
- uses: actions/checkout@v2
28+
- uses: julia-actions/setup-julia@v1
29+
with:
30+
version: ${{ matrix.version }}
31+
arch: ${{ matrix.arch }}
32+
- uses: actions/cache@v1
33+
env:
34+
cache-name: cache-artifacts
35+
with:
36+
path: ~/.julia/artifacts
37+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
38+
restore-keys: |
39+
${{ runner.os }}-test-${{ env.cache-name }}-
40+
${{ runner.os }}-test-
41+
${{ runner.os }}-
42+
- uses: julia-actions/julia-buildpkg@v1
43+
- name: Install latest dependencies
44+
run: julia --project=. -e "using Pkg; Pkg.add(PackageSpec(name=\""DiffinDiffsBase\"", rev=\""master\"")); Pkg.instantiate()"
45+
- uses: julia-actions/julia-runtest@v1
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: CI-stable
2+
on:
3+
pull_request:
4+
branches:
5+
- master
6+
push:
7+
branches:
8+
- master
9+
tags: '*'
10+
jobs:
11+
test:
12+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
13+
env:
14+
JULIA_NUM_THREADS: 2
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
version:
20+
- '1.3'
21+
- '1'
22+
os:
23+
- 'ubuntu-latest'
24+
- 'macos-latest'
25+
- 'windows-latest'
26+
arch:
27+
- 'x64'
28+
steps:
29+
- uses: actions/checkout@v2
30+
- uses: julia-actions/setup-julia@v1
31+
with:
32+
version: ${{ matrix.version }}
33+
arch: ${{ matrix.arch }}
34+
- uses: actions/cache@v1
35+
env:
36+
cache-name: cache-artifacts
37+
with:
38+
path: ~/.julia/artifacts
39+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
40+
restore-keys: |
41+
${{ runner.os }}-test-${{ env.cache-name }}-
42+
${{ runner.os }}-test-
43+
${{ runner.os }}-
44+
- uses: julia-actions/julia-buildpkg@v1
45+
- name: Install latest dependencies
46+
run: julia --project=. -e "using Pkg; Pkg.add(PackageSpec(name=\""DiffinDiffsBase\"", rev=\""master\"")); Pkg.instantiate()"
47+
- uses: julia-actions/julia-runtest@v1
48+
- uses: julia-actions/julia-processcoverage@v1
49+
- uses: codecov/codecov-action@v1
50+
with:
51+
file: lcov.info
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CompatHelper
2+
on:
3+
schedule:
4+
- cron: '00 00 * * 0'
5+
workflow_dispatch:
6+
jobs:
7+
CompatHelper:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Pkg.add("CompatHelper")
11+
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
12+
- name: CompatHelper.main()
13+
env:
14+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15+
COMPATHELPER_PRIV: ${{ secrets.SSH_KEY }}
16+
run: julia -e 'using CompatHelper; CompatHelper.main()'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: TagBot
2+
on:
3+
issue_comment:
4+
types:
5+
- created
6+
workflow_dispatch:
7+
jobs:
8+
TagBot:
9+
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: JuliaRegistries/TagBot@v1
13+
with:
14+
token: ${{ secrets.GITHUB_TOKEN }}
15+
ssh: ${{ secrets.SSH_KEY }}
16+
user: junyuan-chen
17+
18+
gpg: ${{ secrets.GPG_KEY }}
19+
gpg_password: ${{ secrets.GPG_PASSWORD }}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Junyuan Chen
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name = "InteractionWeightedDIDs"
2+
uuid = "4fda0319-85a0-4a01-849e-821b918731ee"
3+
authors = ["Junyuan Chen <[email protected]>"]
4+
version = "0.3.0"
5+
6+
[deps]
7+
DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
8+
DiffinDiffsBase = "7fc23ce2-6e83-4e3c-822f-a79085ccb3e8"
9+
FixedEffectModels = "9d5cd8c9-2029-5cab-9928-427838db53e3"
10+
FixedEffects = "c8885935-8500-56a7-9867-7708b20db0eb"
11+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
12+
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
13+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
14+
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
15+
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
16+
StatsProcedures = "d2f4e7c0-4966-47f3-9552-d63f8a71a436"
17+
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
18+
Vcov = "ec2bfdc2-55df-4fc9-b9ae-4958c2cf2486"
19+
20+
[compat]
21+
DataAPI = "1.5"
22+
DataFrames = "1"
23+
DiffinDiffsBase = "0.4"
24+
FixedEffectModels = "1.6"
25+
FixedEffects = "2"
26+
Reexport = "0.2, 1"
27+
StatsBase = "0.33"
28+
StatsFuns = "0.9"
29+
StatsModels = "0.6"
30+
StatsProcedures = "0.1"
31+
Tables = "1"
32+
Vcov = "0.5"
33+
julia = "1.3"
34+
35+
[extras]
36+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
37+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
38+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
39+
40+
[targets]
41+
test = ["DataFrames", "Dates", "Test"]
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# InteractionWeightedDIDs.jl
2+
3+
*Regression-based multi-period difference-in-differences with heterogenous treatment effects*
4+
5+
[![CI-stable](https://github.com/JuliaDiffinDiffs/InteractionWeightedDIDs.jl/workflows/CI-stable/badge.svg)](https://github.com/JuliaDiffinDiffs/InteractionWeightedDIDs.jl/actions?query=workflow%3ACI-stable)
6+
[![codecov](https://codecov.io/gh/JuliaDiffinDiffs/InteractionWeightedDIDs.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaDiffinDiffs/InteractionWeightedDIDs.jl)
7+
8+
This package provides a collection of regression-based estimators
9+
and auxiliary tools for difference-in-differences (DID)
10+
across multiple treatment groups over multiple time periods.
11+
It is a component of [DiffinDiffs.jl](https://github.com/JuliaDiffinDiffs/DiffinDiffs.jl)
12+
that can also be used as a standalone package.
13+
14+
> **Note:**
15+
>
16+
> The development of this package is not fully complete.
17+
> New features and improvements are being added over time.
18+
19+
## Applicable Environment
20+
21+
The baseline empirical environment this package focuses on
22+
is the same as the one considered by [Sun and Abraham (2020)](https://doi.org/10.1016/j.jeconom.2020.09.006):
23+
24+
* Treatment states are binary, irreversible and sharp.
25+
* Units may receive treatment in different periods in a staggered fashion.
26+
* Treatment effects may evolve over time following possibly heterogenous paths across treated groups.
27+
28+
The parameters of interest include:
29+
30+
* A collection of average treatment effects
31+
on each group of treated units in different periods.
32+
* Interpretable aggregations of these group-time-level parameters.
33+
34+
## Main Features
35+
36+
This package is developed with dedication to
37+
both the credibility of econometric methodology
38+
and high performance for working with relatively large datasets.
39+
40+
The main features are the following:
41+
42+
* Automatic and efficient generation of indicator variables based on empirical design and data coverage.
43+
* Enforcement of an overlap condition based on the parallel trends assumption.
44+
* Fast residualization of regressors from fixed effects via [FixedEffects.jl](https://github.com/FixedEffects/FixedEffects.jl).
45+
* Interaction-weighted DID estimators proposed by [Sun and Abraham (2020)](https://doi.org/10.1016/j.jeconom.2020.09.006).
46+
* Cell-level decomposition of coefficient estimates for analytical reconciliation across specifications.
47+
48+
As a component of [DiffinDiffs.jl](https://github.com/JuliaDiffinDiffs/DiffinDiffs.jl),
49+
it follows the same programming interface shared by all component packages.
50+
In particular, it is benefited from the macros `@did` and `@specset`
51+
that largely simplify the construction of groups of related specifications
52+
and reduce unnecessary repetitions of identical intermediate steps
53+
(e.g., partialling out fixed effects for the same regressors).
54+
Tools for easing the export of estimation results are also being developed.
55+
56+
## Econometric Foundations
57+
58+
The package does not enforce the use of a specific estimation procedure
59+
and allows some flexibility from the users.
60+
However, it is mainly designed to ease the adoption of
61+
recent advances in the difference-in-differences literature
62+
that overcome certain pitfalls that may arise
63+
in scenarios where the treated units get treated in different periods
64+
(i.e., the staggered adoption design).
65+
66+
The development of this package is directly based on the following studies:
67+
* [Sun and Abraham (2020)](https://doi.org/10.1016/j.jeconom.2020.09.006)
68+
* Unpublished work by the package author
69+
70+
Some other studies are also relevant and have provided inspiration:
71+
72+
* [de Chaisemartin and D'Haultfœuille (2020)](https://doi.org/10.1257/aer.20181169)
73+
* [Borusyak and Jaravel (2018)](#BorusyakJ18)
74+
* [Goodman-Bacon (2020)](#Goodman20)
75+
* [Callaway and Sant'Anna (2020)](https://doi.org/10.1016/j.jeconom.2020.12.001)
76+
77+
## References
78+
79+
<a name="BorusyakJ18">**Borusyak, Kirill, and Xavier Jaravel.** 2018. "Revisiting Event Study Designs with an Application to the Estimation of the Marginal Propensity to Consume." Unpublished.</a>
80+
81+
<a name="CallawayS20">**Callaway, Brantly, and Pedro H. C. Sant'Anna.** 2020. "Difference-in-Differences with Multiple Time Periods." *Journal of Econometrics*, forthcoming.</a>
82+
83+
<a name="ChaisemartD20T">**de Chaisemartin, Clément, and Xavier D'Haultfœuille.** 2020. "Two-Way Fixed Effects Estimators with Heterogeneous Treatment Effects." *American Economic Review* 110 (9): 2964-96.</a>
84+
85+
<a name="Goodman20">**Goodman-Bacon, Andrew.** 2020. "Difference-in-Differences with Variation in Treatment Timing." Unpublished.</a>
86+
87+
<a name="SunA20">**Sun, Liyang, and Sarah Abraham.** 2020. "Estimating Dynamic Treatment Effects in Event Studies with Heterogeneous Treatment Effects." *Journal of Econometrics*, forthcoming.</a>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module InteractionWeightedDIDs
2+
3+
using Base: Callable
4+
using DataAPI: refarray
5+
using FixedEffectModels: FixedEffectTerm, Combination,
6+
fe, fesymbol, _multiply, invsym!, isnested, nunique
7+
using FixedEffects
8+
using LinearAlgebra: Cholesky, Factorization, Symmetric, cholesky!, diag
9+
using Reexport
10+
using StatsBase: AbstractWeights, CovarianceEstimator, UnitWeights, PValue, TestStat, NoQuote
11+
using StatsFuns: fdistccdf
12+
using StatsModels: coefnames
13+
using StatsProcedures: _count!
14+
using Tables
15+
using Tables: getcolumn, columnnames
16+
using Vcov
17+
@reexport using DiffinDiffsBase
18+
using DiffinDiffsBase: ValidTimeType, termvars, isintercept, parse_intercept!,
19+
_groupfind, _treatnames, _parse_bycells!, _parse_subset
20+
21+
import Base: show
22+
import DiffinDiffsBase: valid_didargs, vce, treatment, nobs, outcomename, weights, treatnames,
23+
dof_residual, agg, post!
24+
import FixedEffectModels: has_fe
25+
import StatsProcedures: required, default, transformed, combinedargs, copyargs, result
26+
27+
export Vcov,
28+
fe
29+
30+
export CheckVcov,
31+
ParseFEterms,
32+
GroupFEterms,
33+
MakeFEs,
34+
CheckFEs,
35+
MakeFESolver,
36+
MakeYXCols,
37+
MakeTreatCols,
38+
SolveLeastSquares,
39+
EstVcov,
40+
SolveLeastSquaresWeights,
41+
42+
RegressionBasedDID,
43+
Reg,
44+
RegressionBasedDIDResult,
45+
has_fe,
46+
AggregatedRegDIDResult,
47+
has_lsweights,
48+
ContrastResult,
49+
contrast
50+
51+
include("utils.jl")
52+
include("procedures.jl")
53+
include("did.jl")
54+
55+
end

0 commit comments

Comments
 (0)