diff --git a/R/ggcoefplot.R b/R/ggcoefplot.R index 39b8a61..b256a7d 100644 --- a/R/ggcoefplot.R +++ b/R/ggcoefplot.R @@ -55,9 +55,10 @@ #' channel. For example, we can make the CI band lighter with #' `ci.fill.par = list(alpha = 0.2)` (the default alpha is 0.3). #' * `dict` a dictionary for overriding coefficient names. -#' * All other `...` arguments are passed to `summary.fixest` before plotting -#' (e.g., for on-the-fly VCOV adjustment) and will be silently ignored if -#' not relevant. +#' * `vcov`, `cluster` or `se` as alternative options for adjusting the +#' standard errors of the model object(s) on the fly. See `summary.fixest` for +#' details. Written here in superseding order; `cluster` will only be +#' considered if `vcov` is not null, etc. #' @details These functions generally try to mimic the functionality and (where #' appropriate) arguments of `fixest::coefplot` and `fixest::iplot` as #' closely as possible. However, by leveraging the ggplot2 API and diff --git a/R/ggiplot.R b/R/ggiplot.R index 768d8c7..73f2216 100644 --- a/R/ggiplot.R +++ b/R/ggiplot.R @@ -49,6 +49,11 @@ ggiplot = function( ref.line.par = list(col = "black", lty = 2, lwd = 0.3) if (!is.null(dots[["ref.line.par"]])) ref.line.par = utils::modifyList(ref.line.par, dots[["ref.line.par"]]) + # VCOV adjustments (if any) + vcov = if (!is.null(dots[['vcov']])) dots[['vcov']] else NULL + cluster = if (!is.null(dots[['cluster']])) dots[['cluster']] else NULL + se = if (!is.null(dots[['se']])) dots[['se']] else NULL + # The next few blocks grab the underlying iplot/coefplot data, contingent on the # object that was passed into the function (i.e. fixest, fixest_multi, or # list) @@ -57,11 +62,21 @@ ggiplot = function( if (inherits(object, c("fixest", "fixest_multi"))) { if (length(ci_level) == 1) { - data = iplot_data_func(object, .ci_level = ci_level, .dict = dict, .aggr_es = aggr_eff, .keep = keep, .drop = drop, .group = group, .i.select = i.select, ...) + data = iplot_data_func( + object, + .ci_level = ci_level, .dict = dict, .aggr_es = aggr_eff, + .keep = keep, .drop = drop, .group = group, .i.select = i.select, + .vcov = vcov, .cluster = cluster, .se = se + ) } else { data = lapply( ci_level, - function(ci_l) iplot_data_func(object, .ci_level = ci_l, .dict = dict, .aggr_es = aggr_eff, .keep = keep, .drop = drop, .group = group, .i.select = i.select, ...) + function(ci_l) iplot_data_func( + object, + .ci_level = ci_l, .dict = dict, .aggr_es = aggr_eff, + .keep = keep, .drop = drop, .group = group, .i.select = i.select, + .vcov = vcov, .cluster = cluster, .se = se + ) ) data = do.call("rbind", data) } @@ -81,13 +96,18 @@ ggiplot = function( if (length(ci_level) == 1) { data = lapply( object, iplot_data_func, - .ci_level = ci_level, .dict = dict, .aggr_es = aggr_eff, .group = group, .i.select = i.select, ... + .ci_level = ci_level, .dict = dict, .aggr_es = aggr_eff, + .group = group, .i.select = i.select, + .vcov = vcov, .cluster = cluster, .se = se ) } else { data = lapply(ci_level, function(ci_l) { - lapply(object, iplot_data_func, - .ci_level = ci_l, - .dict = dict, .aggr_es = aggr_eff, .group = group, .i.select = i.select, ... + lapply( + object, iplot_data_func, + .ci_level = ci_l, + .dict = dict, .aggr_es = aggr_eff, + .group = group, .i.select = i.select, + .vcov = vcov, .cluster = cluster, .se = se ) }) data = do.call(function(...) Map("rbind", ...), data) diff --git a/R/iplot_data.R b/R/iplot_data.R index b4095b1..a04d28a 100644 --- a/R/iplot_data.R +++ b/R/iplot_data.R @@ -42,9 +42,11 @@ #' aggregated mean treatment effects for some subset of the model should be #' added as a column to the returned data frame. Passed to #' `aggr_es(..., aggregation = "mean")`. -#' @param ... Other arguments passed on to `summary.fixest`, e.g. for -#' post-estimation VCOV adjustment. Irrelevant arguments will be silently -#' ignored. +#' @param .vcov,.cluster,.se Alternative options for adjusting the standard +#' errors of the model object on the fly. See `summary.fixest` for details +#' (although note that the "." period prefix should be ignored in the latter's +#' argument documentation). Written here in superseding order; `.cluster` will +#' only be considered if `.vcov` is not null, etc. #' @details This function is a wrapper around #' `fixest::iplot(..., only.params = TRUE)`, but with various checks and tweaks #' to better facilitate plotting with `ggplot2` and handling of complex object @@ -82,7 +84,9 @@ iplot_data = function( # .aggr_es = c("none", "post", "pre", "both"), .aggr_es = NULL, .group = "auto", - ... + .vcov = NULL, + .cluster = NULL, + .se = NULL ) { # .aggr_es = match.arg(.aggr_es) @@ -99,8 +103,14 @@ iplot_data = function( .group = NULL } - # Catch any args pass through ... to summary.fixest (e.g., vcov adjustments) - object = summary(object, ...) + # Catch VCOV adjustments (if any) + if (!is.null(.vcov)) { + object = summary(object, vcov = .vcov) + } else if (!is.null(.cluster)) { + object = summary(object, cluster = .cluster) + } else if (!is.null(.se)) { + object = summary(object, se = .se) + } p = coefplot(object, only.params = TRUE, ci_level = .ci_level, dict = .dict, keep = .keep, drop = .drop, internal.only.i = .internal.only.i, i.select = .i.select) d = p$prms @@ -432,9 +442,17 @@ coefplot_data = function( .internal.only.i = FALSE, .i.select = 1, .aggr_es = "none", - ... + .vcov = NULL, + .cluster = NULL, + .se = NULL ) { - iplot_data(object, .ci_level = .ci_level, .dict = .dict, .keep = .keep, .drop = .drop, .internal.only.i = .internal.only.i, .group = .group, ...) + iplot_data( + object, + .ci_level = .ci_level, .dict = .dict, + .keep = .keep, .drop = .drop, + .internal.only.i = .internal.only.i, .group = .group, + .vcov = .vcov, .cluster = .cluster, .se = .se + ) } diff --git a/man/ggcoefplot.Rd b/man/ggcoefplot.Rd index 3c5dc1c..5009eb7 100644 --- a/man/ggcoefplot.Rd +++ b/man/ggcoefplot.Rd @@ -70,9 +70,10 @@ are requested for the default pointrange style). The default value is 0.2. channel. For example, we can make the CI band lighter with \code{ci.fill.par = list(alpha = 0.2)} (the default alpha is 0.3). \item \code{dict} a dictionary for overriding coefficient names. -\item All other \code{...} arguments are passed to \code{summary.fixest} before plotting -(e.g., for on-the-fly VCOV adjustment) and will be silently ignored if -not relevant. +\item \code{vcov}, \code{cluster} or \code{se} as alternative options for adjusting the +standard errors of the model object(s) on the fly. See \code{summary.fixest} for +details. Written here in superseding order; \code{cluster} will only be +considered if \code{vcov} is not null, etc. }} \item{aggr_eff}{A keyword string or numeric sequence, indicating whether diff --git a/man/iplot_data.Rd b/man/iplot_data.Rd index d2c2153..3e2a6e4 100644 --- a/man/iplot_data.Rd +++ b/man/iplot_data.Rd @@ -15,7 +15,9 @@ iplot_data( .i.select = 1, .aggr_es = NULL, .group = "auto", - ... + .vcov = NULL, + .cluster = NULL, + .se = NULL ) coefplot_data( @@ -28,7 +30,9 @@ coefplot_data( .internal.only.i = FALSE, .i.select = 1, .aggr_es = "none", - ... + .vcov = NULL, + .cluster = NULL, + .se = NULL ) } \arguments{ @@ -81,9 +85,11 @@ valid uses: ⁠group=list(group_name=1:2)) See the Details section of \code{?fixest::coefplot} for more.} -\item{...}{Other arguments passed on to \code{summary.fixest}, e.g. for -post-estimation VCOV adjustment. Irrelevant arguments will be silently -ignored.} +\item{.vcov, .cluster, .se}{Alternative options for adjusting the standard +errors of the model object on the fly. See \code{summary.fixest} for details +(although note that the "." period prefix should be ignored in the latter's +argument documentation). Written here in superseding order; \code{.cluster} will +only be considered if \code{.vcov} is not null, etc.} } \value{ A data frame consisting of estimate values, confidence intervals,