From 5b709348a53d8d1c60a30432479cac4d581409d1 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 8 Jul 2023 10:42:10 +0200 Subject: [PATCH 1/3] bring back the print method --- NAMESPACE | 2 + R/methods.R | 142 +++++++++++++++++++++++------------------ man/print.boottest.Rd | 37 +++++++++++ man/print.mboottest.Rd | 37 +++++++++++ 4 files changed, 156 insertions(+), 62 deletions(-) create mode 100644 man/print.boottest.Rd create mode 100644 man/print.mboottest.Rd diff --git a/NAMESPACE b/NAMESPACE index 681af92e..4596da39 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,6 +13,8 @@ S3method(mboottest,lm) S3method(nobs,boottest) S3method(nobs,mboottest) S3method(plot,boottest) +S3method(print,boottest) +S3method(print,mboottest) S3method(pval,boottest) S3method(pval,mboottest) S3method(summary,boottest) diff --git a/R/methods.R b/R/methods.R index cce8ee79..3cab1194 100644 --- a/R/methods.R +++ b/R/methods.R @@ -751,68 +751,86 @@ nobs.mboottest <- function(object, ...) { } -# S3 method to print key information for objects of type `boottest` -# @param x object of type boottest -# @param ... Further arguments passed to or from other methods. -# @param digits Number of rounding digits -# @export -# @method print boottest -# @return A scalar containing the effective number of observations -# used in `mboottest` -# @examples -# #' requireNamespace("fwildclusterboot") -# data(voters) -# lm_fit <- lm( -# proposition_vote ~ treatment + ideology1 + log_income + Q1_immigration, -# data = voters -# ) -# boot <- boottest(lm_fit, -# B = 9999, -# param = "treatment", -# clustid = "group_id1" -# ) -# print(boot) -# -# # print.boottest <- function(x, ..., digits = 4) {# stopifnot(inherits(x, "boottest"))## print(x$call)# cat("", "\n")## vals <- lapply(# c("p_val", "conf_int", "t_stat"),# function(y) {# ifelse(is.null(x[[y]]),# 'not computed',# round(x[[y]], digits = digits)# )# }# )## cat("p value:", vals[[1]], "\n")# cat("confidence interval:", vals[[2]], "\n")# cat("test statistic", vals[[3]], "\n")# } - -# S3 method to print key information for objects of type `mboottest` -# @param x object of type mboottest -# @param ... Further arguments passed to or from other methods. -# @param digits Number of rounding digits -# @export -# @method print mboottest -# @return A scalar containing the effective number of observations used -# in `mboottest` -# @examples -# \dontrun{ -# requireNamespace("clubSandwich") -# R <- clubSandwich::constrain_zero(2:3, coef(lm_fit)) -# wboottest <- -# mboottest( -# object = lm_fit, -# clustid = "group_id1", -# B = 999, -# R = R -# ) -# print(wboottest) -# } -# -# print.mboottest <- function(x, ..., digits = 4) { -# stopifnot(inherits(x, "mboottest")) -# -# print(x$call) -# cat("", "\n") -# -# vals <- lapply( -# c("p_val", "teststat"), -# function(y) { -# round(x[[y]], digits = digits) -# } -# ) -# -# cat("p value:", vals[[1]], "\n") -# cat("test statistic", vals[[2]], "\n") -# } + +#' S3 method to print key information for objects of type `bboottest` +#' @param x object of type boottest +#' @param ... Further arguments passed to or from other methods. +#' @param digits Number of rounding digits +#' @export +#' @method print boottest +#' @return A scalar containing the effective number of observations +#' used in `mboottest` +#' @examples +#' #' requireNamespace("fwildclusterboot") +#' data(voters) +#' lm_fit <- lm( +#' proposition_vote ~ treatment + ideology1 + log_income + Q1_immigration, +#' data = voters +#' ) +#' boot <- boottest(lm_fit, +#' B = 9999, +#' param = "treatment", +#' clustid = "group_id1" +#' ) +#' print(boot) +#' +print.boottest <- function(x, ..., digits = 4) { + stopifnot(inherits(x, "boottest")) + + print(x$call) + cat("", "\n") + + vals <- lapply( + c("p_val", "conf_int", "t_stat"), + function(y) { + round(x[[y]], digits = digits) + } + ) + + cat("p value:", vals[[1]], "\n") + cat("confidence interval:", vals[[2]], "\n") + cat("test statistic", vals[[3]], "\n") +} + + +#' S3 method to print key information for objects of type `mboottest` +#' @param x object of type mboottest +#' @param ... Further arguments passed to or from other methods. +#' @param digits Number of rounding digits +#' @export +#' @method print mboottest +#' @return A scalar containing the effective number of observations used +#' in `mboottest` +#' @examples +#' \dontrun{ +#' requireNamespace("clubSandwich") +#' R <- clubSandwich::constrain_zero(2:3, coef(lm_fit)) +#' wboottest <- +#' mboottest( +#' object = lm_fit, +#' clustid = "group_id1", +#' B = 999, +#' R = R +#' ) +#' print(wboottest) +#' } +#' +print.mboottest <- function(x, ..., digits = 4) { + stopifnot(inherits(x, "mboottest")) + + print(x$call) + cat("", "\n") + + vals <- lapply( + c("p_val", "teststat"), + function(y) { + round(x[[y]], digits = digits) + } + ) + + cat("p value:", vals[[1]], "\n") + cat("test statistic", vals[[2]], "\n") +} tidy.mboottest <- function(x, ...) { diff --git a/man/print.boottest.Rd b/man/print.boottest.Rd new file mode 100644 index 00000000..f725cab1 --- /dev/null +++ b/man/print.boottest.Rd @@ -0,0 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/methods.R +\name{print.boottest} +\alias{print.boottest} +\title{S3 method to print key information for objects of type \code{bboottest}} +\usage{ +\method{print}{boottest}(x, ..., digits = 4) +} +\arguments{ +\item{x}{object of type boottest} + +\item{...}{Further arguments passed to or from other methods.} + +\item{digits}{Number of rounding digits} +} +\value{ +A scalar containing the effective number of observations +used in \code{mboottest} +} +\description{ +S3 method to print key information for objects of type \code{bboottest} +} +\examples{ +#' requireNamespace("fwildclusterboot") +data(voters) +lm_fit <- lm( + proposition_vote ~ treatment + ideology1 + log_income + Q1_immigration, + data = voters +) +boot <- boottest(lm_fit, + B = 9999, + param = "treatment", + clustid = "group_id1" +) +print(boot) + +} diff --git a/man/print.mboottest.Rd b/man/print.mboottest.Rd new file mode 100644 index 00000000..73699f53 --- /dev/null +++ b/man/print.mboottest.Rd @@ -0,0 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/methods.R +\name{print.mboottest} +\alias{print.mboottest} +\title{S3 method to print key information for objects of type \code{mboottest}} +\usage{ +\method{print}{mboottest}(x, ..., digits = 4) +} +\arguments{ +\item{x}{object of type mboottest} + +\item{...}{Further arguments passed to or from other methods.} + +\item{digits}{Number of rounding digits} +} +\value{ +A scalar containing the effective number of observations used +in \code{mboottest} +} +\description{ +S3 method to print key information for objects of type \code{mboottest} +} +\examples{ +\dontrun{ +requireNamespace("clubSandwich") +R <- clubSandwich::constrain_zero(2:3, coef(lm_fit)) +wboottest <- + mboottest( + object = lm_fit, + clustid = "group_id1", + B = 999, + R = R + ) +print(wboottest) +} + +} From b53de6773c3b5611d7cee0a1dac1a5f3310c1de2 Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 8 Jul 2023 10:55:05 +0200 Subject: [PATCH 2/3] update docs --- NEWS.md | 7 ++++ .../Multiple-Estimations-with-fixest.Rmd | 38 +++++++++++++++---- vignettes/articles/wild_bootstrap.Rmd | 13 ++++--- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/NEWS.md b/NEWS.md index cf88c41d..8e93acb1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# fwildclusterboot 0.14.1 + +- brings back the `print()` method, it had a use case after all +- some fixes to the documentation + + + # fwildclusterboot 0.14 ## Breaking Changes diff --git a/vignettes/articles/Multiple-Estimations-with-fixest.Rmd b/vignettes/articles/Multiple-Estimations-with-fixest.Rmd index 92217645..42fe73fd 100644 --- a/vignettes/articles/Multiple-Estimations-with-fixest.Rmd +++ b/vignettes/articles/Multiple-Estimations-with-fixest.Rmd @@ -24,7 +24,7 @@ data(voters) ## Variables created via 'i()' -```{r} +```{r, warnings = FALSE, message=FALSE} feols_fit <- feols(proposition_vote ~ i(treatment, ideology1) , data = voters ) @@ -42,7 +42,7 @@ boot1 It is possible to loop through different regression specifications. For example, to run `boottest()` over a `fixest_multi` object created via the `sw()` function: -```{r, warning = FALSE} +```{r, warnings = FALSE, message=FALSE} feols_fits <- fixest::feols( proposition_vote ~ treatment | sw(Q1_immigration, Q2_defense), data = voters @@ -62,7 +62,7 @@ boot2 Similarly, it is possible to loop over objects of `fixest_multi` created by `subset` functionality: -```{r, warning = FALSE} +```{r, warnings = FALSE, message=FALSE} voters$split <- sample(1:2, nrow(voters), TRUE) feols_fits <- fixest::feols( @@ -86,14 +86,14 @@ boot3 And of course it is also possible to combine multiple "syntactic sugar" features of `fixest`: -```{r, warning = FALSE} +```{r, warnings = FALSE, message=FALSE} feols_fits <- fixest::feols( proposition_vote ~ treatment | sw(Q1_immigration, Q2_defense), split = ~split, data = voters ) -boot_4 <- lapply( +boot4 <- lapply( feols_fits, \(x) boottest( x, @@ -103,14 +103,16 @@ boot_4 <- lapply( ) ) -boot_4 +boot4 ``` ## What currently is not supported +As a rule of thumb, every transformation of fixed effects is not supported. This includes interaction via `^` and varying slopes syntax via `var1[var2]`. If you try this, you should receive an error message, and if not, please open an issue on github =) . + Fixed effect interactions via `^` lead to an error. Fixing this is on my backlog but currently not highest priortiy. Send me a message if this causes you large headaches! -```{r, warning = FALSE, eval = FALSE} +```{r, warnings = FALSE, message=FALSE, eval = FALSE} feols_fit2 <- feols(proposition_vote ~ treatment | Q1_immigration^Q2_defense, data = voters ) @@ -121,8 +123,30 @@ boot1 <- boottest(feols_fit2, param = "treatment", clustid = "group_id1" ) +# Error in `check_boottest_args_plus()` at fwildclusterboot/R/boottest_fixest.R:514:2: +# ! Advanced formula notation in fixest / fixest via ^ to interact +# fixed effects is currently not supported in boottest(). + ``` +Relatedly, varying slopes fixed effects syntax is not supported: +```{r, warnings = FALSE, message=FALSE, eval = FALSE} +feols_fit3 <- feols(proposition_vote ~ treatment | Q1_immigration[log_income], + data = voters +) + +# leads to an error +boot <- boottest(feols_fit3, + B = 9999, + param = "treatment", + clustid = "group_id1" +) +# Error in `check_boottest_args_plus()` at fwildclusterboot/R/boottest_fixest.R:514:2: +# ! Varying slopes in fixest / fixest via [] to interact +# fixed effects is currently not supported in boottest(). + + +``` diff --git a/vignettes/articles/wild_bootstrap.Rmd b/vignettes/articles/wild_bootstrap.Rmd index 0ecad36a..e8f46e77 100644 --- a/vignettes/articles/wild_bootstrap.Rmd +++ b/vignettes/articles/wild_bootstrap.Rmd @@ -209,14 +209,15 @@ While inverting bootstrap tests is computationally more demanding, in the case o #### Example: How to compute a CI by test inversion -Suppose we have a parameter $\theta \in \Theta$ and a test statistic $T(\theta)$. We also have a critical value $c$ so that to test the null hypothesis $H_0: \theta = \theta_0$ against $H_1: \theta \neq \theta_0$ at a level $\alpha$, we reject the null hypothesis if $T(\theta_0) > c$. + -Let's define a set that includes all values of $\theta$ for which the decision rule "reject the null hypothesis if $T(\theta)\geq c$" leads to an acceptance of the null hypothesis: + -$$ - C = \{\theta \in \Theta: T(\theta)\leq c \}. -$$ -Based on the definition of the p-value, we can alternatively define a confidence interval at significance level $\alpha$ as + + + + +Based on the definition of the p-value, we can define a confidence interval at significance level $\alpha$ as $$ C = \{\theta \in \Theta: p(\theta) \geq \alpha \}. From 728865f8a3d20b7ac3f8a54ba0225e848d1c237a Mon Sep 17 00:00:00 2001 From: Alexander Fischer Date: Sat, 8 Jul 2023 10:55:15 +0200 Subject: [PATCH 3/3] update docs --- .../Different-Variants-of-the-Wild-Cluster-Bootstrap.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/articles/Different-Variants-of-the-Wild-Cluster-Bootstrap.Rmd b/vignettes/articles/Different-Variants-of-the-Wild-Cluster-Bootstrap.Rmd index 53259986..5b7e9348 100644 --- a/vignettes/articles/Different-Variants-of-the-Wild-Cluster-Bootstrap.Rmd +++ b/vignettes/articles/Different-Variants-of-the-Wild-Cluster-Bootstrap.Rmd @@ -17,7 +17,7 @@ Note that in a recent update of their working paper, MNW have renamed the new bo To run all bootstrap types with the null hypothesis imposed on the bootstrap data generating process, you would have to specify the `bootstrap_type` function argument: -```{r setup, warnings = FALSE} +```{r setup, warnings = FALSE, message=FALSE} library(fwildclusterboot) library(modelsummary) options(modelsummary_factory_default = "gt")