From 67a01ee9a9deda1a35045b50287538579c6ababc Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Mar 2024 14:14:43 +0100 Subject: [PATCH] Check if "weights" exists for vector-method (#485) * Check if "weights" exists for vector-method * wording * fix check * comment * comment * styler * simplify nesting * refactor * comment to structure * styler --- DESCRIPTION | 2 +- R/data_tabulate.R | 2 +- R/data_xtabulate.R | 35 +++++++++++++++++++++++++++-- tests/testthat/test-data_tabulate.R | 1 + 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index eeee80702..34966d0e6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: datawizard Title: Easy Data Wrangling and Statistical Transformations -Version: 0.9.1.5 +Version: 0.9.1.6 Authors@R: c( person("Indrajeet", "Patil", , "patilindrajeet.science@gmail.com", role = "aut", comment = c(ORCID = "0000-0003-1995-6531", Twitter = "@patilindrajeets")), diff --git a/R/data_tabulate.R b/R/data_tabulate.R index 04f205ec8..76c9733b1 100644 --- a/R/data_tabulate.R +++ b/R/data_tabulate.R @@ -141,7 +141,7 @@ data_tabulate.default <- function(x, } # validate "weights" - weights <- .validate_table_weights(weights, x) + weights <- .validate_table_weights(weights, x, weights_expression = insight::safe_deparse(substitute(weights))) # we go into another function for crosstables here... if (!is.null(by)) { diff --git a/R/data_xtabulate.R b/R/data_xtabulate.R index c8e622e2d..ef4edeb27 100644 --- a/R/data_xtabulate.R +++ b/R/data_xtabulate.R @@ -312,8 +312,39 @@ print_html.dw_data_xtabulates <- function(x, big_mark = NULL, ...) { } -.validate_table_weights <- function(weights, x) { - if (!is.null(weights)) { +.validate_table_weights <- function(weights, x, weights_expression = NULL) { + # exception: for vectors, if weighting variable not found, "weights" is NULL. + # to check this, we further need to check whether a weights expression was + # provided, e.g. "weights = iris$not_found" - all this is only relevant when + # weights is NULL + if (is.null(weights)) { + # possibly misspelled weights-variables for default-method ---------------- + # ------------------------------------------------------------------------- + + # do we have any value for weights_expression? + if (!is.null(weights_expression) && + # due to deparse() and substitute, NULL becomes "NULL" - we need to check for this + !identical(weights_expression, "NULL") && + # we should only run into this problem, when a variable from a data frame + # is used in the data_tabulate() method for vectors - thus, we need to check + # whether the weights_expression contains a "$" - `iris$not_found` is "NULL" + # we need this check, because the default-method of data_tabulate() is called + # from the data.frame method, where `weights = weights`, and then, + # deparse(substitute(weights)) is "weights" (not "NULL" or "iris$not_found"), + # leading to an error when actually all is OK (if "weights" is NULL) + # Example: + #> efc$weights <- abs(rnorm(n = nrow(efc), mean = 1, sd = 0.5)) + # Here, efc$wweight is NULL + #> data_tabulate(efc$c172code, weights = efc$wweight) + # Here, wweight errors anyway, because object "wweight" is not found + #> data_tabulate(efc$c172code, weights = wweight) + grepl("$", weights_expression, fixed = TRUE)) { + insight::format_error("The variable specified in `weights` was not found. Possibly misspelled?") + } + } else { + # possibly misspecified weights-variables for data.frame-method ----------- + # ------------------------------------------------------------------------- + if (is.character(weights)) { # If "weights" is a character string, must be of length 1 if (length(weights) > 1) { diff --git a/tests/testthat/test-data_tabulate.R b/tests/testthat/test-data_tabulate.R index 1ca47a967..7b78e06b9 100644 --- a/tests/testthat/test-data_tabulate.R +++ b/tests/testthat/test-data_tabulate.R @@ -363,6 +363,7 @@ test_that("data_tabulate, cross tables, errors weights", { expect_error(data_tabulate(efc, "c172code", weights = efc$weights[-1]), regex = "Length of `weights`") expect_error(data_tabulate(efc, "c172code", weights = "weigths"), regex = "not found") expect_error(data_tabulate(efc, "c172code", weights = c("e16sex", "e42dep")), regex = "length 1") + expect_error(data_tabulate(efc$c172code, weights = efc$wweight), regex = "not found") })