Science Score: 67.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 4 DOI reference(s) in README -
✓Academic publication links
Links to: arxiv.org -
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (15.9%) to scientific vocabulary
Last synced: 6 months ago
·
JSON representation
·
Repository
Generic functions for treatment effects with panel data
Basic Info
Statistics
- Stars: 12
- Watchers: 2
- Forks: 5
- Open Issues: 5
- Releases: 0
Created almost 5 years ago
· Last pushed about 1 year ago
Metadata Files
Readme
Citation
README.Rmd
---
output: github_document
---
```{r, echo = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-"
)
```
```{r, echo=FALSE, results="hide", warning=FALSE, message=FALSE}
devtools::load_all("~/Dropbox/pte")
devtools::load_all("~/Dropbox/ppe")
load("~/Dropbox/ppe/data/covid_data.rda")
library(ggplot2)
library(dplyr)
```
# Panel Treatment Effects (pte) Package
The `pte` package compartmentalizes the steps needed to implement estimators of group-time average treatment effects (and their aggregations) in order to make it easier to apply the same sorts of arguments outside of their "birthplace" in the literature on difference-in-differences.
This code is lightweight, only works for balanced panels, and has minimal error checking. That said, it should be useful projects that build on top of group-time average treatment effects in order to deliver estimates of causal effects in panel data settings.
The main function is called `pte`. The most important paramters that it takes in are `subset_fun` and `attgt_fun`. These are functions that the user should pass to `pte`.
`subset_fun` takes in the overall data, a group, a time period, and possibly other arguments and returns a `data.frame` containing the relevant subset of the data, an outcome, and whether or not a unit should be considered to be in the treated or comparison group for that group/time. There is one example of a relevant subset function provided in the package: [the `two_by_two_subset` function](https://github.com/bcallaway11/pte/blob/master/R/subset_functions.R). This function takes an original dataset, subsets it into pre- and post-treatment periods and denotes treated and untreated units. This particular subset is perhaps the most common/important one for thinking about treatment effects with panel data.
The other main function is `attgt_fun`. This function should be able to take in the correct subset of data, possibly along with other arguments to the function, and report an *ATT* for that subset. With minor modification, this function should be availble for most any sort of treatment effects application --- for example, if you can solve the baseline 2x2 case in difference in differences, you should use that function here, and the `pte` package will take care of dealing with the variation in treatment timing.
If `attgt_fun` returns an influence function, then the `pte` package will also conduct inference using the multiplier bootstrap (which is fast) and produce uniform confidence bands (which adjust for multiple testing).
The default output of `pte` is an overall treatment effect on the treated (i.e., across all groups that participate in the treatment in any time period) and dynamic effects (i.e., event studies). More aggregations are possible, but these seem to be the leading cases; aggregations of group-time average treatment effects are discussed at length in [Callaway and Sant'Anna (2021)](https://doi.org/10.1016/j.jeconom.2020.12.001).
Here are a few examples:
## Example 1: Difference in differences
The [`did` package](https://bcallaway11.github.io/did/), which is based on [Callaway and Sant'Anna (2021)](https://doi.org/10.1016/j.jeconom.2020.12.001), includes estimates of group-time average treatment effects, *ATT(g,t)*, based on a difference in differences identification strategy. The following example demonstrates that it is easy to compute group-time average treatment effects using difference in differences using the `pte` package. [*Note:* This is definitely not the recommended way of doing this as there is very little error handling, etc. here, but it is rather a proof of concept. You should use the `did` package for this case.]
This example reproduces DID estimates of the effect of the minimum wage on employment using data from the `did` package.
```{r}
library(did)
data(mpdta)
did_res <- pte(yname="lemp",
gname="first.treat",
tname="year",
idname="countyreal",
data=mpdta,
setup_pte_fun=setup_pte,
subset_fun=two_by_two_subset,
attgt_fun=did_attgt,
xformla=~lpop)
summary(did_res)
ggpte(did_res)
```
What's most interesting here, is that the only "new" code that needs to be writte is in [the `did_attgt` function](https://github.com/bcallaway11/pte/blob/master/R/attgt_functions.R). You will see that this is a very small amount of code.
## Example 2: Policy Evaluation during a Pandemic
As a next example, consider trying to estimate effects of Covid-19 related policies during a pandemic. The estimates below are for the effects of state-leve shelter-in-place orders during the early part of the pandemic.
[Callaway and Li (2021)](https://arxiv.org/abs/2105.06927) argue that a particular unconfoundedness-type strategy is more appropriate in this context than DID-type strategies due to the spread of Covid-19 cases being highly nonlinear. However, they still deal with the challenge of variation in treatment timing. Therefore, it is still useful to think about group-time average treatment effects, but the DID strategy should be replaced with their particular unconfoundedness type assumption.
The `pte` package is particularly useful here.
```{r}
# formula for covariates
xformla <- ~ current + I(current^2) + region + totalTestResults
```
```{r echo=FALSE, results=FALSE, warning=FALSE}
# drop some data as in paper
trim_id_list <- lapply(c(10,15,20,25,30),
did::trimmer,
tname="time.period",
idname="state_id",
gname="group",
xformla=xformla,
data=covid_data,
control_group="nevertreated",
threshold=0.95)
time_id_list <- unlist(trim_id_list)
# unique(subset(covid_data, state_id %in% time_id_list)$state)
covid_data2 <- subset(covid_data, !(state_id %in% time_id_list))
```
```{r}
covid_res <- pte(yname="positive",
gname="group",
tname="time.period",
idname="state_id",
data=covid_data2,
setup_pte_fun=setup_pte_basic,
subset_fun=two_by_two_subset,
attgt_fun=covid_attgt,
xformla=xformla,
max_e=21,
min_e=-10)
summary(covid_res)
ggpte(covid_res) + ylim(c(-1000,1000))
```
What's most interesting is just how little code needs to be written here. The only new code required is the `ppe::covid_attgt` function which is [available here](https://github.com/bcallaway11/ppe/blob/master/R/covid_attgt.R), and, as you can see, this is very simple.
## Example 3: Empirical Bootstrap
The code above used the multiplier bootstrap. The great thing about the multiplier bootstrap is that it's fast. But in order to use it, you have to work out the influence function for the estimator of *ATT(g,t)*. Although I pretty much always end up doing this, it can be tedious, and it can be nice to get a working version of the code for a project going before working out the details on the influence function.
The `pte` package can be used with the empirical bootstrap. There are a few limitations. First, it's going to be substantially slower. Second, this code just reports pointwise confidence intervals. However, this basically is set up to fit into my typical workflow, and I see this as a way to get preliminary results.
Let's demonstrate it. To do this, consider the same setup as in Example 1, but where no influence function is returned. Let's write the code for this:
```{r}
# did with no influence function
did_attgt_noif <- function(gt_data, xformla, ...) {
# call original function
did_gt <- did_attgt(gt_data, xformla, ...)
# remove influence function
did_gt$inf_func <- NULL
did_gt
}
```
Now, we can show the same sorts of results as above
```{r}
did_res_noif <- pte(yname="lemp",
gname="first.treat",
tname="year",
idname="countyreal",
data=mpdta,
setup_pte_fun=setup_pte,
subset_fun=two_by_two_subset,
attgt_fun=did_attgt_noif, #this is only diff.
xformla=~lpop)
summary(did_res_noif)
ggpte(did_res_noif)
```
What's exciting about this is just how little new code needs to be written.
Owner
- Login: bcallaway11
- Kind: user
- Location: Athens, GA
- Company: University of Georgia
- Website: www.brantlycallaway.com
- Repositories: 23
- Profile: https://github.com/bcallaway11
Brantly Callaway, Department of Economics, University of Georgia
Citation (CITATION.cff)
# --------------------------------------------
# CITATION file created with {cffr} R package
# See also: https://docs.ropensci.org/cffr/
# --------------------------------------------
cff-version: 1.2.0
message: 'To cite package "pte" in publications use:'
type: software
license: GPL-3.0-only
title: 'pte: Panel Treatment Effects'
version: 0.0.0.9000
abstract: This is fairly generic code for estimating treatment effects with panel
data. This is useful code in my own work and will perhaps be useful to others. It
builds heavily on the \codedid package. In particular, it breaks into separate steps
organizing the data, looping over groups and time periods, computing group-time
average treatment effects, and aggregating group-time average treatment effects.
Often, one is able to implement a new identification/estimation procedure by simply
replacing the step on estimating group-time average treatment effects. See several
different examples of this approach in the README.
authors:
- family-names: Callaway
given-names: Brantly
email: brantly.callaway@uga.edu
repository-code: https://github.com/bcallaway11/pte
url: https://github.com/bcallaway11/pte
contact:
- family-names: Callaway
given-names: Brantly
email: brantly.callaway@uga.edu
references:
- type: software
title: BMisc
abstract: 'BMisc: Miscellaneous Functions for Panel Data, Quantiles, and Printing
Results'
notes: Imports
url: https://bcallaway11.github.io/BMisc/
repository: https://CRAN.R-project.org/package=BMisc
authors:
- family-names: Callaway
given-names: Brantly
email: brantly.callaway@uga.edu
year: '2025'
doi: 10.32614/CRAN.package.BMisc
version: '>= 1.4.7'
- type: software
title: Matrix
abstract: 'Matrix: Sparse and Dense Matrix Classes and Methods'
notes: Imports
url: https://R-forge.R-project.org/tracker/?atid=294&group_id=61
repository: https://CRAN.R-project.org/package=Matrix
authors:
- family-names: Bates
given-names: Douglas
orcid: https://orcid.org/0000-0001-8316-9503
- family-names: Maechler
given-names: Martin
email: mmaechler+Matrix@gmail.com
orcid: https://orcid.org/0000-0002-8685-9910
- family-names: Jagan
given-names: Mikael
orcid: https://orcid.org/0000-0002-3542-2938
year: '2025'
doi: 10.32614/CRAN.package.Matrix
- type: software
title: did
abstract: 'did: Treatment Effects with Multiple Periods and Groups'
notes: Imports
url: https://bcallaway11.github.io/did/
repository: https://CRAN.R-project.org/package=did
authors:
- family-names: Callaway
given-names: Brantly
email: brantly.callaway@uga.edu
- family-names: Sant'Anna
given-names: Pedro H. C.
email: pedro.h.santanna@vanderbilt.edu
year: '2025'
doi: 10.32614/CRAN.package.did
version: '>= 2.0.0'
- type: software
title: ggplot2
abstract: 'ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics'
notes: Imports
url: https://ggplot2.tidyverse.org
repository: https://CRAN.R-project.org/package=ggplot2
authors:
- family-names: Wickham
given-names: Hadley
email: hadley@posit.co
orcid: https://orcid.org/0000-0003-4757-117X
- family-names: Chang
given-names: Winston
orcid: https://orcid.org/0000-0002-1576-2126
- family-names: Henry
given-names: Lionel
- family-names: Pedersen
given-names: Thomas Lin
email: thomas.pedersen@posit.co
orcid: https://orcid.org/0000-0002-5147-4711
- family-names: Takahashi
given-names: Kohske
- family-names: Wilke
given-names: Claus
orcid: https://orcid.org/0000-0002-7470-9261
- family-names: Woo
given-names: Kara
orcid: https://orcid.org/0000-0002-5125-4188
- family-names: Yutani
given-names: Hiroaki
orcid: https://orcid.org/0000-0002-3385-7233
- family-names: Dunnington
given-names: Dewey
orcid: https://orcid.org/0000-0002-9415-4582
- family-names: Brand
given-names: Teun
name-particle: van den
orcid: https://orcid.org/0000-0002-9335-7468
year: '2025'
doi: 10.32614/CRAN.package.ggplot2
- type: software
title: DRDID
abstract: 'DRDID: Doubly Robust Difference-in-Differences Estimators'
notes: Imports
url: https://psantanna.com/DRDID/
repository: https://CRAN.R-project.org/package=DRDID
authors:
- family-names: Sant'Anna
given-names: Pedro H. C.
email: pedrosantanna@causal-solutions.com
- family-names: Zhao
given-names: Jun
email: beanzhaojun11@gmail.com
year: '2025'
doi: 10.32614/CRAN.package.DRDID
- type: software
title: tidyr
abstract: 'tidyr: Tidy Messy Data'
notes: Imports
url: https://tidyr.tidyverse.org
repository: https://CRAN.R-project.org/package=tidyr
authors:
- family-names: Wickham
given-names: Hadley
email: hadley@posit.co
- family-names: Vaughan
given-names: Davis
email: davis@posit.co
- family-names: Girlich
given-names: Maximilian
year: '2025'
doi: 10.32614/CRAN.package.tidyr
- type: software
title: dplyr
abstract: 'dplyr: A Grammar of Data Manipulation'
notes: Imports
url: https://dplyr.tidyverse.org
repository: https://CRAN.R-project.org/package=dplyr
authors:
- family-names: Wickham
given-names: Hadley
email: hadley@posit.co
orcid: https://orcid.org/0000-0003-4757-117X
- family-names: François
given-names: Romain
orcid: https://orcid.org/0000-0002-2444-4226
- family-names: Henry
given-names: Lionel
- family-names: Müller
given-names: Kirill
orcid: https://orcid.org/0000-0002-1416-3412
- family-names: Vaughan
given-names: Davis
email: davis@posit.co
orcid: https://orcid.org/0000-0003-4777-038X
year: '2025'
doi: 10.32614/CRAN.package.dplyr
- type: software
title: pbapply
abstract: 'pbapply: Adding Progress Bar to ''*apply'' Functions'
notes: Imports
url: https://github.com/psolymos/pbapply
repository: https://CRAN.R-project.org/package=pbapply
authors:
- family-names: Solymos
given-names: Peter
email: psolymos@gmail.com
orcid: https://orcid.org/0000-0001-7337-1740
- family-names: Zawadzki
given-names: Zygmunt
email: zygmunt@zstat.pl
year: '2025'
doi: 10.32614/CRAN.package.pbapply
- type: software
title: testthat
abstract: 'testthat: Unit Testing for R'
notes: Suggests
url: https://testthat.r-lib.org
repository: https://CRAN.R-project.org/package=testthat
authors:
- family-names: Wickham
given-names: Hadley
email: hadley@posit.co
year: '2025'
doi: 10.32614/CRAN.package.testthat
version: '>= 3.0.0'
GitHub Events
Total
- Issues event: 2
- Watch event: 3
- Issue comment event: 2
- Push event: 7
Last Year
- Issues event: 2
- Watch event: 3
- Issue comment event: 2
- Push event: 7
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 0
- Total pull requests: 1
- Average time to close issues: N/A
- Average time to close pull requests: 1 day
- Total issue authors: 0
- Total pull request authors: 1
- Average comments per issue: 0
- Average comments per pull request: 1.0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 1
- Average time to close issues: N/A
- Average time to close pull requests: 1 day
- Issue authors: 0
- Pull request authors: 1
- Average comments per issue: 0
- Average comments per pull request: 1.0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
- fBedecarrats (1)
Top Labels
Issue Labels
Pull Request Labels
Dependencies
DESCRIPTION
cran
- BMisc >= 1.4.1 imports
- DRDID * imports
- Matrix * imports
- did >= 2.0.0 imports
- dplyr * imports
- ggplot2 * imports
- pbapply * imports
- tidyr * imports
.github/workflows/r.yml
actions
- actions/checkout v2 composite
- r-lib/actions/setup-r f57f1301a053485946083d7a45022b278929a78a composite
.github/workflows/update-citation-cff.yaml
actions
- actions/checkout v2 composite
- r-lib/actions/setup-r v2 composite
- r-lib/actions/setup-r-dependencies v2 composite