Skip to content

Commit

Permalink
version 0.2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaswiemann authored and cran-robot committed Jun 27, 2024
1 parent e9ffa41 commit 702d41e
Show file tree
Hide file tree
Showing 32 changed files with 641 additions and 277 deletions.
10 changes: 5 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: ddml
Title: Double/Debiased Machine Learning
Version: 0.2.1
Date: 2024-05-23
Version: 0.2.2
Date: 2024-06-26
Authors@R: c(
person("Achim", "Ahrens", role = "aut"),
person("Christian B", "Hansen", role = "aut"),
Expand All @@ -10,7 +10,7 @@ Authors@R: c(
Description: Estimate common causal parameters using double/debiased machine
learning as proposed by Chernozhukov et al. (2018) <doi:10.1111/ectj.12097>.
'ddml' simplifies estimation based on (short-)stacking as discussed in
Ahrens et al. (2024) <doi:10.48550/arXiv.2401.01645>, which leverages multiple base
Ahrens et al. (2024) <doi:10.1177/1536867X241233641>, which leverages multiple base
learners to increase robustness to the underlying data generating process.
License: GPL (>= 3)
URL: https://github.com/thomaswiemann/ddml,
Expand All @@ -26,11 +26,11 @@ Suggests: sandwich, covr, testthat (>= 3.0.0), knitr, rmarkdown
Config/testthat/edition: 3
VignetteBuilder: knitr
NeedsCompilation: no
Packaged: 2024-05-25 15:21:14 UTC; thomas
Packaged: 2024-06-26 23:53:58 UTC; thomas
Author: Achim Ahrens [aut],
Christian B Hansen [aut],
Mark E Schaffer [aut],
Thomas Wiemann [aut, cre]
Maintainer: Thomas Wiemann <wiemann@uchicago.edu>
Repository: CRAN
Date/Publication: 2024-05-26 08:00:21 UTC
Date/Publication: 2024-06-27 00:10:02 UTC
60 changes: 31 additions & 29 deletions MD5
Original file line number Diff line number Diff line change
@@ -1,56 +1,58 @@
01ff35ad4fdea8a110acb6950b9965ce *DESCRIPTION
fffca98e58f0c2672ef8ab4c57cd2f35 *NAMESPACE
1fcb43ec811d9bb6a5f1eee6e7a5f490 *NEWS.md
f463c37c7b8c0a71147b364824bdca04 *DESCRIPTION
6bdbcdb8ff8bce517f56f228df723f1a *NAMESPACE
4ac1c6affc7398111d2eadb41398ccd9 *NEWS.md
1c738b4f1dcac94295b0bcf32a0e2b0d *R/AE98.R
942d71d65eef14727bc4ca588e9a0c00 *R/crosspred.R
f46158a1a36679548fb0c5485d237b69 *R/crossval.R
050b797ae303a3ebf5b95e6a43e540bc *R/ddml.R
28bdf0b4c52df9acf5fb7e9bc9242029 *R/ddml_ate.R
8748b7979382b3bad0c80f3a4f46035e *R/ddml_att.R
485519bb3cd1c574008f97895a19781c *R/ddml_fpliv.R
acc1fff94216ced979a06469d1e09ad6 *R/ddml_late.R
db333656b5e85041caf394f7c5a60136 *R/ddml_pliv.R
39105738ccbeb1442351fd3621869e62 *R/ddml_plm.R
3f54ad15ee294bbc4895398c3f030251 *R/ensemble.R
ab6862a1117f929ae7d41b0698b6f957 *R/ddml_ate.R
129e0df4aff128388381d1639c539159 *R/ddml_att.R
fd98edaeee8ebe3e5a2a5a611e3c4c96 *R/ddml_fpliv.R
ceb344fa138acc013b8badf71d6fccc3 *R/ddml_late.R
f8c9d028d6287e30edf6e4b88b1dc7e6 *R/ddml_pliv.R
bf162814547a01260448224f8c829be1 *R/ddml_plm.R
4dddaa45504e773ba5d4cfa7c6701da2 *R/ensemble.R
2f658174fd1cba29b8202c6263321fb1 *R/get_CEF.R
4880595270d9b82a900b8dc8115f3552 *R/help_functions.R
006dec4b24df8988c416d8a03fda3f83 *R/ml_wrappers.R
c8452eb3cece74f7c3dcf724c2b7c4cd *R/ols.R
db6b6fa92cd38f9a8debc50d22580858 *R/help_functions.R
8f8fbebc5b1f8fe292e37943de6897ff *R/ml_wrappers.R
6b747ebc3b723d4b6f1dafa3ddf6001f *R/ols.R
b558c313902d9f9607d9b3ede139b982 *R/shortstacking.R
ee4c39c81fd4add2e297e6827a86eb19 *README.md
34c6a71e648c25a538315a703539a730 *README.md
ab1262ec1c6a326772d567bc6d6ec847 *build/vignette.rds
2167ba7930f91561710c79ec585826c6 *data/AE98.rda
7f87bb966357a01984a2dd0fad5471fe *inst/doc/ddml.Rmd
3e97730b8b89467ade07447782039538 *inst/doc/ddml.html
8ff28ee6ca8314741b6f7e61b6be9554 *inst/doc/ddml.Rmd
a9adacb69edfde465f832406e86cc4bf *inst/doc/ddml.html
ab9f580e562bf4ed00bba8147f6efa73 *man/AE98.Rd
44bc4e0a9d6bd1ecfc41bcd15ecd6185 *man/crosspred.Rd
2d51cf39822d64e47d64162024587149 *man/crossval.Rd
0bd21a93c9e37059870dab917eb15f89 *man/ddml.Rd
ebd940a3e443fbf43578a812a2490168 *man/ddml_ate.Rd
9791b87bca1110541306eeb08fe76bc1 *man/ddml_ate.Rd
33a3317fde756008797f5a86414fe2f9 *man/ddml_fpliv.Rd
cbe43a32886c86fa599d5fa93d13603a *man/ddml_late.Rd
fedc484012d09bd1ec086fff0e7c7ff3 *man/ddml_late.Rd
4ed304b6c83fedf9b212dbb2d65ed8d5 *man/ddml_pliv.Rd
15e8f649c9b2b9f1972bdc7180d441a5 *man/ddml_plm.Rd
5d8d0de7fedd6787a76d149aa91658d9 *man/mdl_glm.Rd
9b46a4cdb40dd74ccadfd91dcc97c51c *man/mdl_glmnet.Rd
e49b8817720f7440ca469697f3c68744 *man/mdl_ranger.Rd
fc6c9feaf286f780e8d1160920ccf4b6 *man/mdl_ranger.Rd
c27c84bf799084031efcce8a717d7a1e *man/mdl_xgboost.Rd
b4a7eeb67cab134ad2b8d5ccaf6a6d10 *man/ols.Rd
4248c6f7600825de648589379c591a4c *man/ols.Rd
2c8af4872e7c566c3cf990898770661c *man/print.summary.ddml_ate.Rd
7866a738c38dd89829aa6b32f0dfc6a8 *man/print.summary.ddml_plm.Rd
bc4385574c686de78add0924089b5094 *man/shortstacking.Rd
b87de57a62041c41c7e5903fb93ab4b3 *man/summary.ddml_ate.Rd
ec4662cb8c0f9c2e07bb788c8fda6542 *man/summary.ddml_plm.Rd
4ee56cae8617b38b06d73249565ca84b *tests/testthat.R
a3f2b3ce53c526c17e90ddfd22525461 *tests/testthat/test-crosspred.R
2aa456391b4c90bfc98b6b9b774db039 *tests/testthat/test-crossval.R
0461fc73da445d42d45e2f86e04e0460 *tests/testthat/test-ddml_ate.R
4995a218e71a9fe4f2a251a87dd49713 *tests/testthat/test-ddml_att.R
52c77f8735a72bfada5475e3520360e0 *tests/testthat/test-ddml_fpliv.R
5778114b57ed9487eda6d9ac070fe261 *tests/testthat/test-ddml_late.R
2a2c6192f724f2a13030b84a469cd069 *tests/testthat/test-ddml_pliv.R
c507c823ba97becff62fdbb5f6ac0f58 *tests/testthat/test-ddml_plm.R
af9a9c9d125c20f81eab43cc8c682252 *tests/testthat/test-crossval.R
5b70d048151161506292d374c431038b *tests/testthat/test-ddml_ate.R
d9ed4d26d48081071e7c5632ab71006b *tests/testthat/test-ddml_att.R
8de04e7512fa69c05a9ea2c6b50f41ee *tests/testthat/test-ddml_fpliv.R
7216712178d4db8b05760f3c6bbc4942 *tests/testthat/test-ddml_late.R
9f0aa4420ce85e7f134bbaddf5f90fc9 *tests/testthat/test-ddml_pliv.R
f7336fc729608718dab2746cc4608a51 *tests/testthat/test-ddml_plm.R
3ec43fad27aa50e119b4ce9e4a7be5d1 *tests/testthat/test-ensemble.R
b7b3a95edd9c882099f050cefdcd85fc *tests/testthat/test-help_functions.R
2dcb9e3b29724ead06d35b94241f9cec *tests/testthat/test-ml_wrappers.R
4aa96c4872f751778a8effabe94cd74a *tests/testthat/test-ml_wrappers.R
a127e214bcf0fe7c77debb68b0260706 *tests/testthat/test-ols.R
95adbd481f9920433d78470a99991c64 *tests/testthat/test-shortstacking.R
7f87bb966357a01984a2dd0fad5471fe *vignettes/ddml.Rmd
8ff28ee6ca8314741b6f7e61b6be9554 *vignettes/ddml.Rmd
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Generated by roxygen2: do not edit by hand

S3method(print,summary.ddml_ate)
S3method(print,summary.ddml_att)
S3method(print,summary.ddml_fpliv)
S3method(print,summary.ddml_late)
S3method(print,summary.ddml_pliv)
S3method(print,summary.ddml_plm)
S3method(summary,ddml_ate)
S3method(summary,ddml_att)
S3method(summary,ddml_fpliv)
Expand Down
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# ddml 0.2.2

* Changes ``ddml:ols()`` default to ``const=TRUE``.
* Adds probability forest compatibility to ``ddml::mdl_ranger()``.
* Adds propensity score trimming option to ``ddml::ddml_ate()``, ``ddml::ddml_att()``, and ``ddml::ddml_late()``.
* Fixes ATE and LATE scores.
* Fixes output of ``ddml::print.summary.ddml_plm`` and ``ddml::print.summary.ddml_ate`` (#57).

# ddml 0.2.1

* Fixes permuted residuals returned by ``ddml::crossval`` (#54).
Expand Down
68 changes: 58 additions & 10 deletions R/ddml_ate.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#' corresponding to a subsample containing vectors with subsample indices
#' for cross-validation. Arguments are separated for untreated and treated
#' observations, respectively.
#' @param trim Number in (0, 1) for trimming the estimated propensity scores at
#' \code{trim} and \code{1-trim}.
#'
#' @return \code{ddml_ate} and \code{ddml_att} return an object of S3 class
#' \code{ddml_ate} and \code{ddml_att}, respectively. An object of class
Expand All @@ -53,6 +55,8 @@
#' \item{\code{psi_a}, \code{psi_b}}{Matrices needed for the computation
#' of scores. Used in [ddml::summary.ddml_ate()] or
#' [ddml::summary.ddml_att()].}
#' \item{\code{oos_pred}}{List of matrices, providing the reduced form
#' predicted values.}
#' \item{\code{learners},\code{learners_DX},
#' \code{subsamples_D0},\code{subsamples_D1},
#' \code{cv_subsamples_list_D0},\code{cv_subsamples_list_D1},
Expand Down Expand Up @@ -114,6 +118,7 @@ ddml_ate <- function(y, D, X,
subsamples_D1 = NULL,
cv_subsamples_list_D0 = NULL,
cv_subsamples_list_D1 = NULL,
trim = 0.01,
silent = FALSE) {
# Data parameters
nobs <- length(y)
Expand All @@ -140,7 +145,7 @@ ddml_ate <- function(y, D, X,
}# FOR
}#IF

# Merge subsamples across treatment and create auxilliary control matrix
# Merge subsamples across treatment and create auxiliary control matrix
subsamples <- subsamples_D0
cv_subsamples_list <- cv_subsamples_list_D0
auxilliary_X_D0 <- rep(list(NULL), sample_folds)
Expand All @@ -159,7 +164,7 @@ ddml_ate <- function(y, D, X,
cv_subsamples_list[[k]][[j]] <- sort(c(indx_D0, indx_D1))
}#FOR

# Auxilliary X
# Auxiliary X
auxilliary_X_D1[[k]] <- X[-is_D0, , drop=F][subsamples_D1[[k]], , drop=F]
auxilliary_X_D0[[k]] <- X[is_D0, , drop=F][subsamples_D0[[k]], , drop=F]
}#FOR
Expand Down Expand Up @@ -220,11 +225,14 @@ ddml_ate <- function(y, D, X,
}#IF
m_X <- D_X_res$oos_fitted

# Trim propensity scores, return warnings
m_X_tr <- trim_propensity_scores(m_X, trim, ensemble_type)

# Compute the ATE using the constructed variables
y_copy <- matrix(rep(y, nensb), nobs, nensb)
D_copy <- matrix(rep(D, nensb), nobs, nensb)
psi_b <- D_copy * (y_copy - g_D1) / m_X +
(1 - D_copy) * (y_copy - g_D0) / (1 - m_X) + g_D1 - g_D0
psi_b <- D_copy * (y_copy - g_D1) / m_X_tr -
(1 - D_copy) * (y_copy - g_D0) / (1 - m_X_tr) + g_D1 - g_D0
ate <- colMeans(psi_b)
names(ate) <- ensemble_type

Expand All @@ -241,9 +249,13 @@ ddml_ate <- function(y, D, X,
y_X_D1 = y_X_D1_res$mspe,
D_X = D_X_res$mspe)

# Organize reduced form predicted values
oos_pred <- list(EY_D0_X = g_D0, EY_D1_X = g_D1, ED_X = m_X)

# Organize output
ddml_fit <- list(ate = ate, weights = weights, mspe = mspe,
psi_a = psi_a, psi_b = psi_b,
oos_pred = oos_pred,
learners = learners,
learners_DX = learners_DX,
subsamples_D0 = subsamples_D0,
Expand Down Expand Up @@ -290,10 +302,46 @@ summary.ddml_ate <- function(object, ...) {
# Check whether stacking was used, replace ensemble type if TRUE
single_learner <- ("what" %in% names(object$learners))
if (single_learner) object$ensemble_type <- " "
# Compute and print inference results
cat("ATE estimation results: \n \n")
organize_interactive_inf_results(coef = object$ate,
psi_a = object$psi_a,
psi_b = object$psi_b,
ensemble_type = object$ensemble_type)
# Compute and return inference results
coefficients <- organize_interactive_inf_results(coef = object$ate,
psi_a = object$psi_a,
psi_b = object$psi_b,
ensemble_type =
object$ensemble_type)
class(coefficients) <- c("summary.ddml_ate", class(coefficients))
coefficients
}#SUMMARY.DDML_ATE

#' Print Methods for Treatment Effect Estimators.
#'
#' @description Inference methods for treatment effect estimators.
#'
#' @param x An object of class \code{summary.ddml_ate},
#' \code{summary.ddml_att}, and \code{ddml_late}, as returned by
#' [ddml::summary.ddml_ate()], [ddml::summary.ddml_att()], and
#' [ddml::summary.ddml_late()], respectively.
#' @param digits The number of significant digits used for printing.
#' @param ... Currently unused.
#'
#' @return NULL.
#'
#' @export
#'
#' @examples
#' # Construct variables from the included Angrist & Evans (1998) data
#' y = AE98[, "worked"]
#' D = AE98[, "morekids"]
#' X = AE98[, c("age","agefst","black","hisp","othrace","educ")]
#'
#' # Estimate the average treatment effect using a single base learner, ridge.
#' ate_fit <- ddml_ate(y, D, X,
#' learners = list(what = mdl_glmnet,
#' args = list(alpha = 0)),
#' sample_folds = 2,
#' silent = TRUE)
#' summary(ate_fit)
print.summary.ddml_ate <- function(x, digits = 3, ...) {
cat("ATE estimation results: \n \n")
class(x) <- class(x)[-1]
print(x, digits = digits)
}#PRINT.SUMMARY.DDML_ATE
31 changes: 25 additions & 6 deletions R/ddml_att.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ddml_att <- function(y, D, X,
subsamples_D1 = NULL,
cv_subsamples_list_D0 = NULL,
cv_subsamples_list_D1 = NULL,
trim = 0.01,
silent = FALSE) {
# Data parameters
nobs <- length(y)
Expand Down Expand Up @@ -115,12 +116,15 @@ ddml_att <- function(y, D, X,
}#IF
m_X <- D_X_res$oos_fitted

# Trim propensity scores, return warnings
m_X_tr <- trim_propensity_scores(m_X, trim, ensemble_type)

# Compute the ATT using the constructed variables
y_copy <- matrix(rep(y, nensb), nobs, nensb)
D_copy <- matrix(rep(D, nensb), nobs, nensb)
p_copy <- matrix(rep(D_res$oos_fitted, nensb), nobs, nensb)
psi_b <- D_copy * (y_copy - g_D0) / p_copy -
m_X * (1 - D_copy) * (y_copy - g_D0) / (p_copy * (1 - m_X))
m_X_tr * (1 - D_copy) * (y_copy - g_D0) / (p_copy * (1 - m_X_tr))
psi_a <- -D_copy / p_copy
att <- -colMeans(psi_b) / colMeans(psi_a)
names(att) <- ensemble_type
Expand All @@ -133,9 +137,13 @@ ddml_att <- function(y, D, X,
mspe <- list(y_X_D0 = y_X_D0_res$mspe,
D_X = D_X_res$mspe)

# Organize reduced form predicted values
oos_pred <- list(EY_D0_X = g_D0, ED_X = m_X, ED = D_res$oos_fitted)

# Organize output
ddml_fit <- list(att = att, weights = weights, mspe = mspe,
psi_a = psi_a, psi_b = psi_b,
oos_pred = oos_pred,
learners = learners,
learners_DX = learners_DX,
subsamples_D0 = subsamples_D0,
Expand All @@ -160,9 +168,20 @@ summary.ddml_att <- function(object, ...) {
single_learner <- ("what" %in% names(object$learners))
if (single_learner) object$ensemble_type <- " "
# Compute and print inference results
cat("ATT estimation results: \n \n")
organize_interactive_inf_results(coef = object$att,
psi_a = object$psi_a,
psi_b = object$psi_b,
ensemble_type = object$ensemble_type)
coefficients <- organize_interactive_inf_results(coef = object$att,
psi_a = object$psi_a,
psi_b = object$psi_b,
ensemble_type =
object$ensemble_type)
class(coefficients) <- c("summary.ddml_att", class(coefficients))
coefficients
}#SUMMARY.DDML_ATT

#' @rdname print.summary.ddml_ate
#'
#' @export
print.summary.ddml_att <- function(x, digits = 3, ...) {
cat("ATT estimation results: \n \n")
class(x) <- class(x)[-1]
print(x, digits = digits)
}#PRINT.SUMMARY.DDML_ATT
18 changes: 14 additions & 4 deletions R/ddml_fpliv.R
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,18 @@ summary.ddml_fpliv <- function(object, ...) {
single_learner <- ("what" %in% names(object$learners))
if (single_learner) object$ensemble_type <- "single base learner"
# Compute and print inference results
cat("FPLIV estimation results: \n \n")
organize_inf_results(fit_obj_list = object$iv_fit,
ensemble_type = object$ensemble_type,
...)
coefficients <- organize_inf_results(fit_obj_list = object$iv_fit,
ensemble_type = object$ensemble_type,
...)
class(coefficients) <- c("summary.ddml_fpliv", class(coefficients))
coefficients
}#SUMMARY.DDML_FPLIV

#' @rdname print.summary.ddml_plm
#'
#' @export
print.summary.ddml_fpliv <- function(x, digits = 3, ...) {
cat("FPLIV estimation results: \n \n")
class(x) <- class(x)[-1]
print(x, digits = digits)
}#PRINT.SUMMARY.DDML_FPLIV
Loading

0 comments on commit 702d41e

Please sign in to comment.