diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 949c6d58..c2edbaa4 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -24,7 +24,6 @@ jobs: - {os: ubuntu-latest, r: 'release'} - {os: ubuntu-latest, r: 'oldrel-1'} - {os: ubuntu-latest, r: 'oldrel-2'} - - {os: ubuntu-latest, r: 'oldrel-3'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} diff --git a/DESCRIPTION b/DESCRIPTION index deb45db9..33b5f585 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -48,6 +48,7 @@ Suggests: ggeffects (>= 1.3.2), ggstats (>= 0.2.1), glmmTMB, + glmtoolbox, glue, gt, gtsummary (>= 2.0.0), diff --git a/NAMESPACE b/NAMESPACE index c51c9175..b3c3c96c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -73,6 +73,7 @@ S3method(model_get_terms,betareg) S3method(model_get_terms,brmsfit) S3method(model_get_terms,cch) S3method(model_get_terms,default) +S3method(model_get_terms,fixest) S3method(model_get_terms,glmmTMB) S3method(model_get_terms,model_fit) S3method(model_get_weights,default) diff --git a/NEWS.md b/NEWS.md index 65a2afc3..8ddd1f78 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,10 +1,21 @@ # broom.helpers (development version) +**New supported models** + +- support for `glmtoolbox::glmgee()` models (#274) + +**New features** + +- support of instrumental variables for `fixest` models (#279) +- new argument `instrumental_suffix` for `model_list_variables()`, + `tidy_add_variable_labels()` and `tidy_plus_plus()` + **Fixes** - variable labels are now returned by `model_list_variables()` for `svycoxph` models (#275) - compatibility with R version 4.1 minimum (#276) +- fix for `tidy_add_n()` with models with a subset argument (#278) # broom.helpers 1.17.0 diff --git a/R/broom.helpers-package.R b/R/broom.helpers-package.R index fb4e2029..0fc1595b 100644 --- a/R/broom.helpers-package.R +++ b/R/broom.helpers-package.R @@ -51,7 +51,7 @@ utils::globalVariables(c(".")) dplyr::any_of( c( "y.level", "component", "term", "original_term", "variable", - "var_label", "var_class", "var_type", + "instrumental", "var_label", "var_class", "var_type", "var_nlevels", "header_row", "contrasts", "contrasts_type", "reference_row", "label", "n_obs", "n_ind", "n_event", "exposure" ) diff --git a/R/model_compute_terms_contributions.R b/R/model_compute_terms_contributions.R index b9f7cd84..034c2754 100644 --- a/R/model_compute_terms_contributions.R +++ b/R/model_compute_terms_contributions.R @@ -84,8 +84,7 @@ model_compute_terms_contributions.default <- function(model) { } # stop # continuous variables converted to 1 to force positive values - d <- model |> purrr::pluck("data") - if (is.null(d)) d <- model |> model_get_model_frame() + d <- model |> model_get_model_frame() if (is.null(d)) { return(NULL) diff --git a/R/model_get_model_frame.R b/R/model_get_model_frame.R index caf76e0b..3633c3d2 100644 --- a/R/model_get_model_frame.R +++ b/R/model_get_model_frame.R @@ -90,5 +90,8 @@ model_get_model_frame.model_fit <- function(model) { #' @export #' @rdname model_get_model_frame model_get_model_frame.fixest <- function(model) { - stats::model.frame.default(model$fml, data = get(model$call$data, model$call_env)) + stats::model.frame.default( + model_get_terms(model), + data = get(model$call$data, model$call_env) + ) } diff --git a/R/model_get_model_matrix.R b/R/model_get_model_matrix.R index 75b70fb7..448b5090 100644 --- a/R/model_get_model_matrix.R +++ b/R/model_get_model_matrix.R @@ -112,8 +112,16 @@ model_get_model_matrix.model_fit <- function(model, ...) { #' @export #' @rdname model_get_model_matrix +#' @details +#' For `fixest` models, will recreate a model matrix with both main variables +#' and instrumental variables. For more options, see +#' [fixest::model.matrix.fixest]. model_get_model_matrix.fixest <- function(model, ...) { - stats::model.matrix.default(model$fml, data = get(model$call$data, model$call_env), ...) + stats::model.matrix.default( + model_get_terms(model), + data = get(model$call$data, model$call_env), + ... + ) } #' @export diff --git a/R/model_get_terms.R b/R/model_get_terms.R index 84ba9fd1..4d0fcd8e 100644 --- a/R/model_get_terms.R +++ b/R/model_get_terms.R @@ -64,10 +64,34 @@ model_get_terms.betareg <- function(model) { } #' @export -#' @rdname model_get_model_matrix -model_get_terms.cch <- function(model, ...) { +#' @rdname model_get_terms +model_get_terms.cch <- function(model) { stats::terms.formula( model$call$formula |> stats::formula(), data = model |> model_get_model_frame() ) } + +#' @export +#' @rdname model_get_terms +#' @details +#' For `fixest` models, return a term object combining main variables and +#' instrumental variables. +#' +model_get_terms.fixest <- function(model) { + fml <- model$fml + fiv <- model$iv_endo_fml + + if (is.null(fiv)) { + f <- fml + } else { + f <- + paste( + deparse(fml), + "+", + deparse(fiv[[3]]) + ) |> + stats::as.formula() + } + stats::terms(f) +} diff --git a/R/model_list_variables.R b/R/model_list_variables.R index e9ff0efa..548654f3 100644 --- a/R/model_list_variables.R +++ b/R/model_list_variables.R @@ -11,6 +11,9 @@ #' If `TRUE`, will return only "variable" column. #' @param add_var_type (`logical`)\cr #' If `TRUE`, add `var_nlevels` and `var_type` columns. +#' @param instrumental_suffix (`string`)\cr +#' Suffix added to variable labels for instrumental variables (`fixest` models). +#' `NULL` to add nothing. #' @return #' A tibble with three columns: #' * `variable`: the corresponding variable @@ -54,15 +57,21 @@ #' ) |> #' model_list_variables() #' } -model_list_variables <- function(model, labels = NULL, - only_variable = FALSE, add_var_type = FALSE) { +model_list_variables <- function(model, + labels = NULL, + only_variable = FALSE, + add_var_type = FALSE, + instrumental_suffix = " (instrumental)") { UseMethod("model_list_variables") } #' @rdname model_list_variables #' @export -model_list_variables.default <- function(model, labels = NULL, - only_variable = FALSE, add_var_type = FALSE) { +model_list_variables.default <- function(model, + labels = NULL, + only_variable = FALSE, + add_var_type = FALSE, + instrumental_suffix = " (instrumental)") { model_frame <- model_get_model_frame(model) model_terms <- model_get_terms(model) @@ -105,6 +114,19 @@ model_list_variables.default <- function(model, labels = NULL, return(res$variable) } + # specific case for instrumental variables + if (inherits(model, "fixest") && !is.null(instrumental_suffix)) { + iv <- all.vars(model$iv_endo_fml) + res <- res |> + dplyr::mutate( + var_label = dplyr::if_else( + .data$variable %in% iv, + paste0(.data$var_label, instrumental_suffix), + .data$var_label + ) + ) + } + if (add_var_type) { return(.add_var_type(res, model)) } @@ -115,8 +137,11 @@ model_list_variables.default <- function(model, labels = NULL, #' @rdname model_list_variables #' @export -model_list_variables.lavaan <- function(model, labels = NULL, - only_variable = FALSE, add_var_type = FALSE) { +model_list_variables.lavaan <- function(model, + labels = NULL, + only_variable = FALSE, + add_var_type = FALSE, + instrumental_suffix = " (instrumental)") { res <- tibble::tibble( variable = .clean_backticks(unique(model@ParTable$lhs)) ) |> @@ -150,8 +175,11 @@ model_list_variables.lavaan <- function(model, labels = NULL, #' @rdname model_list_variables #' @export -model_list_variables.logitr <- function(model, labels = NULL, - only_variable = FALSE, add_var_type = FALSE) { +model_list_variables.logitr <- function(model, + labels = NULL, + only_variable = FALSE, + add_var_type = FALSE, + instrumental_suffix = " (instrumental)") { res <- model_list_variables.default(model, labels, FALSE) if (!is.null(model$data$scalePar)) { diff --git a/R/tidy_add_reference_rows.R b/R/tidy_add_reference_rows.R index 97b5c00c..0b608263 100644 --- a/R/tidy_add_reference_rows.R +++ b/R/tidy_add_reference_rows.R @@ -156,6 +156,11 @@ tidy_add_reference_rows <- function( x$var_label <- NA_character_ } # temporary populate it + has_instrumental <- "instrumental" %in% names(x) + if (!has_instrumental) { + x$instrumental <- NA + } # temporary populate it + x <- x |> dplyr::mutate( reference_row = dplyr::if_else( @@ -186,7 +191,11 @@ tidy_add_reference_rows <- function( ref_rows <- terms_levels |> dplyr::filter(.data$reference) |> dplyr::mutate(reference_row = TRUE) |> - dplyr::select(dplyr::all_of(c("term", "variable", "label", "reference_row", "rank"))) + dplyr::select( + dplyr::all_of( + c("term", "variable", "label", "reference_row", "rank") + ) + ) if (!"label" %in% names(x)) { ref_rows <- ref_rows |> dplyr::select(-all_of("label")) @@ -204,6 +213,7 @@ tidy_add_reference_rows <- function( var_class = dplyr::first(.data$var_class), var_type = dplyr::first(.data$var_type), var_label = dplyr::first(.data$var_label), + instrumental = dplyr::first(.data$instrumental), var_nlevels = dplyr::first(.data$var_nlevels), effect = dplyr::first(.data$effect), contrasts = dplyr::first(.data$contrasts), @@ -244,6 +254,10 @@ tidy_add_reference_rows <- function( x <- x |> dplyr::select(-dplyr::all_of("var_label")) } + if (!has_instrumental) { + x <- x |> dplyr::select(-dplyr::all_of("instrumental")) + } + x |> dplyr::arrange(.data$rank) |> dplyr::select(-dplyr::all_of("rank")) |> diff --git a/R/tidy_add_variable_labels.R b/R/tidy_add_variable_labels.R index a41613c7..71b6dbda 100644 --- a/R/tidy_add_variable_labels.R +++ b/R/tidy_add_variable_labels.R @@ -16,6 +16,9 @@ #' A tidy tibble as produced by `tidy_*()` functions. #' @param labels ([`formula-list-selector`][gtsummary::syntax])\cr #' An optional named list or a named vector of custom variable labels. +#' @param instrumental_suffix (`string`)\cr +#' Suffix added to variable labels for instrumental variables (`fixest` models). +#' `NULL` to add nothing. #' @param model (a model object, e.g. `glm`)\cr #' The corresponding model, if not attached to `x`. #' @inheritParams tidy_plus_plus @@ -42,6 +45,7 @@ tidy_add_variable_labels <- function(x, labels = NULL, interaction_sep = " * ", + instrumental_suffix = " (instrumental)", model = tidy_get_model(x)) { if (is.null(model)) { cli::cli_abort(c( @@ -85,7 +89,11 @@ tidy_add_variable_labels <- function(x, .update_vector(additional_labels) # add the list of variables from model_list_variables - variable_list <- model_list_variables(model, labels = labels) + variable_list <- model_list_variables( + model, + labels = labels, + instrumental_suffix = instrumental_suffix + ) additional_labels <- variable_list$var_label names(additional_labels) <- variable_list$variable var_labels <- var_labels |> diff --git a/R/tidy_identify_variables.R b/R/tidy_identify_variables.R index ec1d128d..62250ba0 100644 --- a/R/tidy_identify_variables.R +++ b/R/tidy_identify_variables.R @@ -19,6 +19,9 @@ #' #' For dichotomous and categorical variables, `var_nlevels` corresponds to the number #' of original levels in the corresponding variables. +#' +#' For `fixest` models, a new column `instrumental` is added to indicate +#' instrumental variables. #' @param x (`data.frame`)\cr #' A tidy tibble as produced by `tidy_*()` functions. #' @param model (a model object, e.g. `glm`)\cr @@ -65,6 +68,20 @@ tidy_identify_variables <- function(x, model = tidy_get_model(x), .attributes <- .save_attributes(x) + # specific case for fixest models to handle instrumental variables + if (inherits(model, "fixest")) { + x <- x |> + dplyr::mutate( + original_term = .data$term, + instrumental = .data$term |> stringr::str_starts("fit_"), + term = dplyr::if_else( + .data$term |> stringr::str_starts("fit_"), + .data$term |> stringr::str_sub(5), + .data$term + ) + ) + } + # specific case for marginal means / effects / predictions / contrasts if ( isTRUE( diff --git a/R/tidy_plus_plus.R b/R/tidy_plus_plus.R index 255984eb..9f6f6cfb 100644 --- a/R/tidy_plus_plus.R +++ b/R/tidy_plus_plus.R @@ -34,6 +34,9 @@ #' (respectively named `"model_frame"` and `"model_matrix"`) and passed through. #' @param variable_labels ([`formula-list-selector`][gtsummary::syntax])\cr #' A named list or a named vector of custom variable labels. +#' @param instrumental_suffix (`string`)\cr +#' Suffix added to variable labels for instrumental variables (`fixest` models). +#' `NULL` to add nothing. #' @param term_labels (`list` or `vector`)\cr #' A named list or a named vector of custom term labels. #' @param interaction_sep (`string`)\cr @@ -153,6 +156,7 @@ tidy_plus_plus <- function(model, exponentiate = FALSE, model_matrix_attr = TRUE, variable_labels = NULL, + instrumental_suffix = " (instrumental)", term_labels = NULL, interaction_sep = " * ", categorical_terms_pattern = "{level}", @@ -222,7 +226,8 @@ tidy_plus_plus <- function(model, res <- res |> tidy_add_variable_labels( labels = variable_labels, - interaction_sep = interaction_sep + interaction_sep = interaction_sep, + instrumental_suffix = instrumental_suffix ) |> tidy_add_term_labels( labels = term_labels, diff --git a/data-raw/DATASET.R b/data-raw/DATASET.R index f2a0032f..2597c9ff 100644 --- a/data-raw/DATASET.R +++ b/data-raw/DATASET.R @@ -53,7 +53,8 @@ supported_models <- "`pscl::zeroinfl()`", "Use `tidy_zeroinfl()` as `tidy_fun`.", "`pscl::hurdle()`", "Use `tidy_zeroinfl()` as `tidy_fun`.", "`betareg::betareg()`", "Use `tidy_parameters()` as `tidy_fun` with `component` argument to control with coefficients to return. `broom::tidy()` does not support the `exponentiate` argument for betareg models, use `tidy_parameters()` instead.", # nolint - "`survival::cch()`", "`Experimental support." + "`survival::cch()`", "`Experimental support.", + "`glmtoolbox::glmgee()`", "", ) |> dplyr::arrange(.data$model, .locale = "en") diff --git a/data/supported_models.rda b/data/supported_models.rda index 84871d8e..4c278319 100644 Binary files a/data/supported_models.rda and b/data/supported_models.rda differ diff --git a/man/model_get_model_matrix.Rd b/man/model_get_model_matrix.Rd index c3b25c10..0b7ea18a 100644 --- a/man/model_get_model_matrix.Rd +++ b/man/model_get_model_matrix.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/model_get_model_matrix.R, R/model_get_terms.R +% Please edit documentation in R/model_get_model_matrix.R \name{model_get_model_matrix} \alias{model_get_model_matrix} \alias{model_get_model_matrix.default} @@ -14,7 +14,6 @@ \alias{model_get_model_matrix.LORgee} \alias{model_get_model_matrix.betareg} \alias{model_get_model_matrix.cch} -\alias{model_get_terms.cch} \title{Get the model matrix of a model} \usage{ model_get_model_matrix(model, ...) @@ -42,8 +41,6 @@ model_get_model_matrix(model, ...) \method{model_get_model_matrix}{betareg}(model, ...) \method{model_get_model_matrix}{cch}(model, ...) - -\method{model_get_terms}{cch}(model, ...) } \arguments{ \item{model}{(a model object, e.g. \code{glm})\cr @@ -63,6 +60,10 @@ taking into account all components ("cond", "zi" and "disp"). For a more restricted model matrix, please refer to \code{glmmTMB::model.matrix.glmmTMB()}. For \code{\link[plm:plm]{plm::plm()}} models, constant columns are not removed. + +For \code{fixest} models, will recreate a model matrix with both main variables +and instrumental variables. For more options, see +\link[fixest:model.matrix.fixest]{fixest::model.matrix.fixest}. } \examples{ lm(hp ~ mpg + factor(cyl), mtcars) |> diff --git a/man/model_get_terms.Rd b/man/model_get_terms.Rd index f5caf80a..b969abac 100644 --- a/man/model_get_terms.Rd +++ b/man/model_get_terms.Rd @@ -7,6 +7,8 @@ \alias{model_get_terms.glmmTMB} \alias{model_get_terms.model_fit} \alias{model_get_terms.betareg} +\alias{model_get_terms.cch} +\alias{model_get_terms.fixest} \title{Get the terms of a model} \usage{ model_get_terms(model) @@ -22,6 +24,10 @@ model_get_terms(model) \method{model_get_terms}{betareg}(model) \method{model_get_terms}{betareg}(model) + +\method{model_get_terms}{cch}(model) + +\method{model_get_terms}{fixest}(model) } \arguments{ \item{model}{(a model object, e.g. \code{glm})\cr @@ -35,6 +41,9 @@ or \code{NULL} if it is not possible to get terms from \code{model}. For models fitted with \code{glmmTMB::glmmTMB()}, it will return a terms object taking into account all components ("cond" and "zi"). For a more restricted terms object, please refer to \code{glmmTMB::terms.glmmTMB()}. + +For \code{fixest} models, return a term object combining main variables and +instrumental variables. } \examples{ lm(hp ~ mpg + factor(cyl), mtcars) |> diff --git a/man/model_list_variables.Rd b/man/model_list_variables.Rd index 84623e62..0c403d23 100644 --- a/man/model_list_variables.Rd +++ b/man/model_list_variables.Rd @@ -11,28 +11,32 @@ model_list_variables( model, labels = NULL, only_variable = FALSE, - add_var_type = FALSE + add_var_type = FALSE, + instrumental_suffix = " (instrumental)" ) \method{model_list_variables}{default}( model, labels = NULL, only_variable = FALSE, - add_var_type = FALSE + add_var_type = FALSE, + instrumental_suffix = " (instrumental)" ) \method{model_list_variables}{lavaan}( model, labels = NULL, only_variable = FALSE, - add_var_type = FALSE + add_var_type = FALSE, + instrumental_suffix = " (instrumental)" ) \method{model_list_variables}{logitr}( model, labels = NULL, only_variable = FALSE, - add_var_type = FALSE + add_var_type = FALSE, + instrumental_suffix = " (instrumental)" ) } \arguments{ @@ -48,6 +52,10 @@ If \code{TRUE}, will return only "variable" column.} \item{add_var_type}{(\code{logical})\cr If \code{TRUE}, add \code{var_nlevels} and \code{var_type} columns.} + +\item{instrumental_suffix}{(\code{string})\cr +Suffix added to variable labels for instrumental variables (\code{fixest} models). +\code{NULL} to add nothing.} } \value{ A tibble with three columns: diff --git a/man/supported_models.Rd b/man/supported_models.Rd index 50979159..317e4597 100644 --- a/man/supported_models.Rd +++ b/man/supported_models.Rd @@ -31,6 +31,7 @@ Listing of Supported Models \code{gam::gam()} \tab \cr \code{geepack::geeglm()} \tab \cr \code{glmmTMB::glmmTMB()} \tab \code{broom.mixed} package required \cr + \code{glmtoolbox::glmgee()} \tab \cr \code{lavaan::lavaan()} \tab Limited support for categorical variables \cr \code{lfe::felm()} \tab \cr \code{lme4::glmer.nb()} \tab \code{broom.mixed} package required \cr @@ -40,7 +41,7 @@ Listing of Supported Models \code{MASS::glm.nb()} \tab \cr \code{MASS::polr()} \tab \cr \code{mgcv::gam()} \tab Use default tidier \code{broom::tidy()} for smooth terms only, or \code{gtsummary::tidy_gam()} to include parametric terms \cr - \code{mice::mira} \tab Limited support. If \code{mod} is a \code{mira} object, use \code{tidy_fun = function(x, ...) {mice::pool(x) \%>\% mice::tidy(...)}} \cr + \code{mice::mira} \tab Limited support. If \code{mod} is a \code{mira} object, use \verb{tidy_fun = function(x, ...) \{mice::pool(x) |> mice::tidy(...)\}} \cr \code{mmrm::mmrm()} \tab \cr \code{multgee::nomLORgee()} \tab Experimental support. Use \code{tidy_multgee()} as \code{tidy_fun}. \cr \code{multgee::ordLORgee()} \tab Experimental support. Use \code{tidy_multgee()} as \code{tidy_fun}. \cr diff --git a/man/tidy_add_variable_labels.Rd b/man/tidy_add_variable_labels.Rd index eab0617b..c1a655f2 100644 --- a/man/tidy_add_variable_labels.Rd +++ b/man/tidy_add_variable_labels.Rd @@ -8,6 +8,7 @@ tidy_add_variable_labels( x, labels = NULL, interaction_sep = " * ", + instrumental_suffix = " (instrumental)", model = tidy_get_model(x) ) } @@ -21,6 +22,10 @@ An optional named list or a named vector of custom variable labels.} \item{interaction_sep}{(\code{string})\cr Separator for interaction terms.} +\item{instrumental_suffix}{(\code{string})\cr +Suffix added to variable labels for instrumental variables (\code{fixest} models). +\code{NULL} to add nothing.} + \item{model}{(a model object, e.g. \code{glm})\cr The corresponding model, if not attached to \code{x}.} } diff --git a/man/tidy_identify_variables.Rd b/man/tidy_identify_variables.Rd index 525c6240..736dbf11 100644 --- a/man/tidy_identify_variables.Rd +++ b/man/tidy_identify_variables.Rd @@ -39,6 +39,9 @@ will fail to identify the list of variables For dichotomous and categorical variables, \code{var_nlevels} corresponds to the number of original levels in the corresponding variables. + +For \code{fixest} models, a new column \code{instrumental} is added to indicate +instrumental variables. } \examples{ df <- Titanic |> diff --git a/man/tidy_plus_plus.Rd b/man/tidy_plus_plus.Rd index 2f05300c..e76da3ac 100644 --- a/man/tidy_plus_plus.Rd +++ b/man/tidy_plus_plus.Rd @@ -12,6 +12,7 @@ tidy_plus_plus( exponentiate = FALSE, model_matrix_attr = TRUE, variable_labels = NULL, + instrumental_suffix = " (instrumental)", term_labels = NULL, interaction_sep = " * ", categorical_terms_pattern = "{level}", @@ -63,6 +64,10 @@ Whether model frame and model matrix should be added as attributes of \code{mode \item{variable_labels}{(\code{\link[gtsummary:syntax]{formula-list-selector}})\cr A named list or a named vector of custom variable labels.} +\item{instrumental_suffix}{(\code{string})\cr +Suffix added to variable labels for instrumental variables (\code{fixest} models). +\code{NULL} to add nothing.} + \item{term_labels}{(\code{list} or \code{vector})\cr A named list or a named vector of custom term labels.} diff --git a/tests/testthat/test-add_n.R b/tests/testthat/test-add_n.R index 259ceb8a..a5129eb1 100644 --- a/tests/testthat/test-add_n.R +++ b/tests/testthat/test-add_n.R @@ -282,3 +282,15 @@ test_that("tidy_add_n() works with lavaan::lavaan", { expect_error(res <- mod |> tidy_and_attach() |> tidy_add_n(), NA) expect_true(all(is.na(res$n))) }) + +test_that("model_compute_terms_contributions() with subset", { + mod <- glm(mpg ~ gear, data = mtcars, subset = mpg < 30) + expect_warning( + res <- mod |> model_compute_terms_contributions(), + NA + ) + expect_equal( + nrow(res), + nrow(mtcars[mtcars$mpg < 30, ]) + ) +}) diff --git a/tests/testthat/test-add_term_labels.R b/tests/testthat/test-add_term_labels.R index 252dde02..5ed535fd 100644 --- a/tests/testthat/test-add_term_labels.R +++ b/tests/testthat/test-add_term_labels.R @@ -254,7 +254,8 @@ test_that("tidy_add_term_labels() works with variables having non standard name" ) ) - res <- lm( + res <- + lm( response ~ `age at dx` + `drug type`, data = gtsummary::trial |> dplyr::select(response, `age at dx` = age, `drug type` = trt) diff --git a/tests/testthat/test-tidy_plus_plus.R b/tests/testthat/test-tidy_plus_plus.R index 72ed9b9c..7748f36a 100644 --- a/tests/testthat/test-tidy_plus_plus.R +++ b/tests/testthat/test-tidy_plus_plus.R @@ -693,6 +693,25 @@ test_that("tidy_plus_plus() works with fixest models", { res <- mod |> tidy_plus_plus(), NA ) + + mod <- fixest::feols(mpg ~ disp | cyl | wt ~ qsec, data = mtcars) + expect_error( + res <- mod |> tidy_plus_plus(), + NA + ) + expect_equal(nrow(res), 2L) + expect_true(res$instrumental[res$term == "wt"]) + res <- mod |> tidy_plus_plus(instrumental_suffix = NULL) + expect_equivalent(res$var_label[res$term == "wt"], "wt") + res <- mod |> tidy_plus_plus(instrumental_suffix = " (IV)") + expect_equivalent(res$var_label[res$term == "wt"], "wt (IV)") + + mod <- fixest::feols(mpg ~ disp | 1 | factor(cyl) ~ qsec, data = mtcars) + expect_error( + res <- mod |> tidy_plus_plus(), + NA + ) + expect_equal(nrow(res[res$instrumental, ]), 3L) }) test_that("tidy_plus_plus() works with logitr models", { @@ -960,3 +979,23 @@ test_that("tidy_post_fun argument of `tidy_plus_plus()`", { # test for survival::cch() not working, model.frame() not working # in the test_that environment for this type of model + +test_that("tidy_plus_plus() works with glmtoolbox::glmgee() models", { + skip_on_cran() + skip_if_not_installed("glmtoolbox") + + data("spruces", package = "glmtoolbox") + + mod <- glmtoolbox::glmgee( + size ~ poly(days, 4) + treat, + id = tree, + family = Gamma(log), + corstr = "AR-M-dependent(1)", + data = spruces + ) + expect_error( + res <- mod |> tidy_plus_plus(), + NA + ) + expect_equal(nrow(res), 6) +}) diff --git a/vignettes/tidy.Rmd b/vignettes/tidy.Rmd index 344df100..ac7f2228 100644 --- a/vignettes/tidy.Rmd +++ b/vignettes/tidy.Rmd @@ -296,7 +296,7 @@ td {vertical-align: top;} # nolint start tibble::tribble( ~Column, ~Function, ~Description, - "original_term", "`tidy_disambiguate_terms()`, `tidy_multgee()` or `tidy_zeroinfl()`", "Original term before disambiguation. This columns is added only when disambiguation is needed (i.e. for mixed models). Also used for \"multgee\", \"zeroinfl\" and \"hurdle\" models.", + "original_term", "`tidy_disambiguate_terms()`, `tidy_multgee()`, `tidy_zeroinfl()` or `tidy_identify_variables()`", "Original term before disambiguation. This columns is added only when disambiguation is needed (i.e. for mixed models). Also used for \"multgee\", \"zeroinfl\" and \"hurdle\" models. For instrumental variables in \"fixest\" models, the \"fit_\" prefix is removed, and the original terms is stored in this column.", "variable", "`tidy_identify_variables()`", "String of variable names from the model. For categorical variables and polynomial terms defined with `stats::poly()`, terms belonging to the variable are identified.", "var_class", "`tidy_identify_variables()`", "Class of the variable.", "var_type", "`tidy_identify_variables()`", "One of \"intercept\", \"continuous\", \"dichotomous\", \"categorical\", \"interaction\", \"ran_pars\" or \"ran_vals\"", @@ -310,7 +310,8 @@ tibble::tribble( "n_obs", "`tidy_add_n()`", "Number of observations", "n_ind", "`tidy_add_n()`", "Number of individuals (for Cox models)", "n_event", "`tidy_add_n()`", "Number of events (for binomial and multinomial logistic models, Poisson and Cox models)", - "exposure", "`tidy_add_n()`", "Exposure time (for Poisson and Cox models)" + "exposure", "`tidy_add_n()`", "Exposure time (for Poisson and Cox models)", + "instrumental", "`tidy_identify_variables()`", "For \"fixest\" models, indicate if a variable was instrumental." ) |> gt::gt() |> gt::fmt_markdown(columns = everything()) |>