Skip to content

Commit 298fe78

Browse files
authored
Merge branch 'main' into inv_propensity_model
2 parents a38e50a + dbaa17b commit 298fe78

File tree

13 files changed

+482
-86
lines changed

13 files changed

+482
-86
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
python-version: ["3.8", "3.9", "3.10"]
14+
python-version: ["3.10", "3.11"]
1515

1616
steps:
1717
- uses: actions/checkout@v3
@@ -26,7 +26,7 @@ jobs:
2626
runs-on: ubuntu-latest
2727
strategy:
2828
matrix:
29-
python-version: ["3.8", "3.9", "3.10"]
29+
python-version: ["3.10", "3.11"]
3030

3131
steps:
3232
- uses: actions/checkout@v3

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
fetch-depth: 0
1818
- uses: actions/setup-python@v4
1919
with:
20-
python-version: 3.8
20+
python-version: 3.11
2121
- name: Build the sdist and the wheel
2222
run: |
2323
pip install build
@@ -62,7 +62,7 @@ jobs:
6262
repository_url: https://test.pypi.org/legacy/
6363
- uses: actions/setup-python@v4
6464
with:
65-
python-version: 3.8
65+
python-version: 3.11
6666
- name: Test pip install from test.pypi
6767
run: |
6868
# Give time to test.pypi to update its index. If we don't wait,

CONTRIBUTING.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ For more instructions see the [Pull request checklist](#pull-request-checklist)
4747

4848
Always use a feature branch. It's good practice to never routinely work on the `main` branch of any repository.
4949
50-
1. Create a new environment using Python >=3.8, for example 3.11
50+
1. Create a new environment using Python >=3.10, for example 3.11
5151
5252
```bash
5353
conda create --name CausalPy python=3.11
@@ -62,16 +62,17 @@ For more instructions see the [Pull request checklist](#pull-request-checklist)
6262
Install the package (in editable mode) and its development dependencies:
6363
6464
```bash
65-
pip install -e .
65+
pip install --no-deps -e .
6666
```
6767
6868
Install development dependencies
6969
70-
```
70+
```bash
7171
pip install 'causalpy[dev]'
7272
pip install 'causalpy[docs]'
7373
pip install 'causalpy[test]'
7474
pip install 'causalpy[lint]'
75+
pip install 'pylint'
7576
```
7677
7778
It may also be necessary to [install](https://pandoc.org/installing.html) `pandoc`. On a mac, run `brew install pandoc`.

Makefile

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,21 @@ init:
44
python -m pip install -e .
55

66
lint:
7-
pip install causalpy[lint]
87
ruff check --fix .
98
ruff format .
109

1110
check_lint:
12-
pip install causalpy[lint]
1311
ruff check .
1412
ruff format --diff --check .
1513
nbqa black --check .
1614
nbqa ruff .
1715
interrogate .
1816

1917
doctest:
20-
pip install causalpy[test]
2118
pytest --doctest-modules --ignore=causalpy/tests/ causalpy/
2219

2320
test:
24-
pip install causalpy[test]
2521
pytest
2622

2723
uml:
28-
pip install pylint
2924
pyreverse -o png causalpy --output-directory docs/source/_static --ignore tests

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ Interrupted time series analysis is appropriate when you have a time series of o
178178

179179
| Frequentist | Bayesian |
180180
|--|--|
181-
| coming soon | ![](https://raw.githubusercontent.com/pymc-labs/CausalPy/main/docs/source/_static/interrupted_time_series_pymc.svg) |
181+
| ![](https://raw.githubusercontent.com/pymc-labs/CausalPy/main/docs/source/_static/interrupted_time_series_skl.svg) | ![](https://raw.githubusercontent.com/pymc-labs/CausalPy/main/docs/source/_static/interrupted_time_series_pymc.svg) |
182182

183183
> The data, pre-treatment model fit, and counterfactual are plotted (top). The causal impact is shown as a blue shaded region. The Bayesian analysis shows shaded Bayesian credible regions of the model fit and counterfactual. Also shown is the causal impact (middle) and cumulative causal impact (bottom).
184184

causalpy/version.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
"""CausalPy Version"""
2-
__version__ = "0.2.2"
2+
3+
__version__ = "0.2.3"
Lines changed: 32 additions & 0 deletions
Loading

docs/source/design_notation.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Quasi-experimental design notation
2+
3+
This page provides a concise summary of the tabular notation used by {cite:t}`shadish_cook_cambell_2002` and {cite:t}`reichardt2019quasi`. This notation provides a compact description of various experimental designs. While it is possible to describe randomised designs using this notation, we focus purely on {term}`quasi-experimental<Quasi-experiment>` designs here, with non-random allocation (abbreviated as `NR`). Observations are denoted by $O$. Time proceeds from left to right, so observations made through time are labelled as $O_1$, $O_2$, etc. The treatment is denoted by `X`. Rows represent different groups of units. Remember, a unit is a person, place, or thing that is the subject of the study.
4+
5+
## Pretest-posttest designs
6+
7+
One of the simplest designs is the pretest-posttest design. Here we have one row, denoting a single group of units. There is an `X` which means all are treated. The pretest is denoted by $O_1$ and the posttest by $O_2$. See p99 of {cite:t}`reichardt2019quasi`.
8+
9+
| | | |
10+
|----|---|----|
11+
$O_1$ | X | $O_2$ |
12+
13+
Informally, if we think about drawing conclusions about the {term}`causal impact` of the treatment based on the change from $O_1$ to $O_2$, we might say that the treatment caused the change. However, this is a tenuous conclusion because we have no way of knowing what would have happened in the ({term}`counterfactual`) absence of the treatment.
14+
15+
A variation of this design which may (slightly) improve this situation from the perspective of making causal claims, would be to take multiple pretest measures. This is shown below, see p107 of {cite:t}`reichardt2019quasi`.
16+
17+
| | | | |
18+
|----|--|---|----|
19+
$O_1$ | $O_2$ | X | $O_3$ |
20+
21+
This would allow us to estimate how the group was changing over time before the treatment was introduced. This could be used to make a stronger causal claim about the impact of the treatment. We could use {term}`interrupted time series<ITS>` analysis to help here.
22+
23+
## Nonequivalent group designs
24+
25+
In randomized experiments, with large enough groups, the randomization process should ensure that the treatment and control groups are approximately equivalent in terms of their attributes. This is positive for causal inference as we can be more sure that differences between control and test groups are due to treatment exposure, not because of differences in attributes of the groups.
26+
27+
However, in quasi-experimental designs, with non-random (`NR`) allocation, we could expect there to be differences between the treatment and control groups' attributes. This poses some challenges in making strong causal claims about the impact of the treatment - we can't be sure that differences between the groups at the posttest are due to the treatment, or due to pre-existing differences between the groups.
28+
29+
In the simplest {term}`nonequivalent group design<NEGD>`, we have two groups, one treated and one not treated, and just one posttest. See p114 of {cite:t}`reichardt2019quasi`.
30+
31+
| | | |
32+
|-----|---|----|
33+
| NR: | X | $O_1$ |
34+
| NR: | | $O_1$ |
35+
36+
The above design would be considered weak - the lack of a pre-test measure makes it hard to know whether differences between the groups at $O_1$ are due to the treatment or to pre-existing differences between the groups.
37+
38+
This limitation can be addressed by adding a pretest measure. See p115 of {cite:t}`reichardt2019quasi`.
39+
40+
| | | | |
41+
|-----|----|---|----|
42+
| NR: | $O_1$ | X | $O_2$ |
43+
| NR: | $O_1$ | | $O_2$ |
44+
45+
Non-equivalent group designs like this, with a pretest and a posttest measure could be analysed in a number of ways:
46+
1. **{term}`ANCOVA`:** Here, the group would be a categorical predictor (e.g. treated/untreated), the pretest measure would be a covariate (though there could be more than one), and the posttest measure would be the outcome.
47+
2. **{term}`Difference in differences`:** We can apply linear modeling approaches such as `y ~ group + time + group:time` to estimate the treatment effect. Here, `y` is the outcome measure, `group` is a binary variable indicating treatment or control group, and `time` is a binary variable indicating pretest or posttest. Note that this approach has a strong assumption of [parallel trends](https://en.wikipedia.org/wiki/Difference_in_differences#Assumptions) - that the treatment and control groups would have changed in the same way in the absence of the treatment.
48+
49+
A limitation of the nonequivalent group designs with single pre and posttest measures is that we don't know how the groups were changing over time before the treatment was introduced. This can be addressed by adding multiple pretest measures and can help in assessing if the parallel trends assumption is reasonable. See p154 of {cite:t}`reichardt2019quasi`.
50+
51+
| | | | | |
52+
|-----|----|---|-|----|
53+
| NR: | $O_1$ | $O_2$ | X | $O_3$ |
54+
| NR: | $O_1$ | $O_2$ | | $O_3$ |
55+
56+
Again, this design could be analysed using the difference-in-differences approach.
57+
58+
## Interrupted time series designs
59+
60+
While there is no control group, the {term}`interrupted time series design` is a powerful quasi-experimental design that can be used to estimate the causal impact of a treatment. The design involves multiple pretest and posttest measures. The treatment is introduced at a specific point in time, denoted by `X`. The design can be used to estimate the causal impact of the treatment by comparing the trajectory of the outcome variable before and after the treatment. See p203 of {cite:t}`reichardt2019quasi`.
61+
62+
| | | | | | | | | |
63+
|-----|----|---|----|---|----|----|----|----|
64+
| $O_1$ | $O_2$ | $O_3$ | $O_4$ | X | $O_5$ | $O_6$ | $O_7$ | $O_8$ |
65+
66+
You can see that this is an example of a pretest-posttest design with multiple pre and posttest measures.
67+
68+
## Comparative interrupted time series designs
69+
70+
The {term}`comparative interrupted time-series<CITS>` design incorporates aspects of **interrupted time series** (with only a treatment group), and **nonequivalent group designs** (with a treatment and control group). This design can be used to estimate the causal impact of a treatment by comparing the trajectory of the outcome variable before and after the treatment in the treatment group, and comparing this to the trajectory of the outcome variable in the control group. See p226 of {cite:t}`reichardt2019quasi`.
71+
72+
| | | | | | | | | | |
73+
|-----|----|---|----|---|----|----|----|----|-|
74+
| NR: | $O_1$ | $O_2$ | $O_3$ | $O_4$ | X | $O_5$ | $O_6$ | $O_7$ | $O_8$ |
75+
| NR: | $O_1$ | $O_2$ | $O_3$ | $O_4$ | | $O_5$ | $O_6$ | $O_7$ | $O_8$ |
76+
77+
78+
Because this design is very similar to the nonequivalent group design, simply with multiple pre and posttest measures, it is well-suited to analysis under the difference-in-differences approach.
79+
80+
However, if we have many untreated units and one treated unit, then this design could be analysed with the {term}`synthetic control` approach.
81+
82+
## Regression discontinuity designs
83+
84+
The design notation for {term}`regression discontinuity designs<RDD>` are different from the others and take a bit of getting used to. We have two groups, but allocation to the groups are determined by a units' relation to a cutoff point `C` along a {term}`running variable`. Also, $O_1$ now represents the value of the running variable, and $O_2$ represents the outcome variable. See p169 of {cite:t}`reichardt2019quasi`. This will make more sense if you consider the design notation alongside one of the example notebooks.
85+
86+
| | | | |
87+
|-----|----|---|----|
88+
| C: | $O_1$ | X | $O_2$ |
89+
| C: | $O_1$ | | $O_2$ |
90+
91+
From an analysis perspective, regression discontinuity designs are very similar to interrupted time series designs. The key difference is that treatment is determined by a cutoff point along a running variable, rather than by time.
92+
93+
## Summary
94+
This page has offered a brief overview of the tabular notation used to describe quasi-experimental designs. The notation is a useful tool for summarizing the design of a study, and can be used to help identify the strengths and limitations of a study design. But readers are strongly encouraged to consult the original sources when assessing the relative strengths and limitations of making causal claims under different quasi-experimental designs.
95+
96+
## References
97+
:::{bibliography}
98+
:filter: docname in docnames
99+
:::

docs/source/glossary.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Glossary
1818
Change score analysis
1919
A statistical procedure where the outcome variable is the difference between the posttest and protest scores.
2020

21+
Causal impact
22+
An umbrella term for the estimated effect of a treatment on an outcome.
23+
2124
Comparative interrupted time-series
2225
CITS
2326
An interrupted time series design with added comparison time series observations.
@@ -36,7 +39,6 @@ Glossary
3639
ITS
3740
A quasi-experimental design to estimate a treatment effect where a series of observations are collected before and after a treatment. No control group is present.
3841

39-
4042
Instrumental Variable regression
4143
IV
4244
A quasi-experimental design to estimate a treatment effect where the is a risk of confounding between the treatment and the outcome due to endogeniety.
@@ -46,7 +48,7 @@ Glossary
4648

4749
Non-equivalent group designs
4850
NEGD
49-
A quasi-experimental design where units are assigned to conditions non-randomly, and not according to a running variable (see Regression discontinuity design).
51+
A quasi-experimental design where units are assigned to conditions non-randomly, and not according to a running variable (see Regression discontinuity design). This can be problematic when assigning causal influence of the treatment - differences in outcomes between groups could be due to the treatment or due to differences in the group attributes themselves.
5052

5153
One-group posttest-only design
5254
A design where a single group is exposed to a treatment and assessed on an outcome measure. There is no pretest measure or comparison group.
@@ -67,11 +69,15 @@ Glossary
6769
An emprical comparison used to estimate the effects of treatments where units are assigned to treatment conditions randomly.
6870

6971
Regression discontinuity design
72+
RDD
7073
A quasi–experimental comparison to estimate a treatment effect where units are assigned to treatment conditions based on a cut-off score on a quantitative assignment variable (aka running variable).
7174

7275
Regression kink design
7376
A quasi-experimental research design that estimates treatment effects by analyzing the impact of a treatment or intervention precisely at a defined threshold or "kink" point in a quantitative assignment variable (running variable). Unlike traditional regression discontinuity designs, regression kink design looks for a change in the slope of an outcome variable at the kink, instead of a discontinuity. This is useful when the assignment variable is not discrete, jumping from 0 to 1 at a threshold. Instead, regression kink designs are appropriate when there is a change in the first derivative of the assignment function at the kink point.
7477

78+
Running variable
79+
In regression discontinuity designs, the running variable is the variable that determines the assignment of units to treatment or control conditions. This is typically a continuous variable. Examples could include a test score, age, income, or spatial location. But the running variable would not be time, which is the case in interrupted time series designs.
80+
7581
Sharp regression discontinuity design
7682
A Regression discontinuity design where allocation to treatment or control is determined by a sharp threshold / step function.
7783

@@ -88,7 +94,6 @@ Glossary
8894
Wilkinson notation
8995
A notation for describing statistical models :footcite:p:`wilkinson1973symbolic`.
9096

91-
9297
Two Stage Least Squares
9398
2SLS
9499
An estimation technique for estimating the parameters of an IV regression. It takes its name from the fact that it uses two OLS regressions - a first and second stage.

docs/source/index.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ Documentation outline
144144
=====================
145145

146146
.. toctree::
147-
:titlesonly:
147+
:caption: Knowledge Base
148148

149-
glossary
149+
design_notation.md
150+
glossary.rst
150151

151152
.. toctree::
152153
:caption: Examples

0 commit comments

Comments
 (0)