diff --git a/NAMESPACE b/NAMESPACE index 43f5d3d5c..f222cfdee 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -40,7 +40,9 @@ export(ard_stats_paired_t_test) export(ard_stats_paired_wilcox_test) export(ard_stats_prop_test) export(ard_stats_t_test) +export(ard_stats_t_test_onesample) export(ard_stats_wilcox_test) +export(ard_stats_wilcox_test_onesample) export(ard_survey_svychisq) export(ard_survey_svyranktest) export(ard_survey_svyttest) diff --git a/NEWS.md b/NEWS.md index 1b3f8e7ff..7b8e77c93 100644 --- a/NEWS.md +++ b/NEWS.md @@ -37,6 +37,8 @@ ard_moodtest() -> ard_stats_mood_test() - `ard_survey_svyranktest()` for weighted/survey rank tests using `survey::svyranktest()`. (#71) - `ard_car_vif()` for calculating the variance inflation factor using `car::vif()`. (#10) - `ard_emmeans_mean_difference()` for calculating the least-squares mean differences using the {emmeans} package. (#34) + - `ard_stats_wilcox_test_onesample()` for calculating one-sample results. + - `ard_stats_t_test_onesample()` for calculating one-sample results. * Updated functions `ard_stats_t_test()`, `ard_stats_paired_t_test()`, `ard_stats_wilcox_test()`, `ard_stats_paired_wilcox_test()`, `ard_stats_chisq_test()`, `ard_stats_fisher_test()`, `ard_stats_kruskal_test()`, `ard_stats_mcnemar_test()`, and `ard_stats_mood_test()` to accept multiple variables at once. Independent tests are calculated for each variable. The `variable` argument is renamed to `variables`. (#77) diff --git a/R/ard_stats_t_test_onesample.R b/R/ard_stats_t_test_onesample.R new file mode 100644 index 000000000..9eb8a79c0 --- /dev/null +++ b/R/ard_stats_t_test_onesample.R @@ -0,0 +1,71 @@ +#' ARD one-sample t-test +#' +#' @description +#' Analysis results data for one-sample t-tests. +#' Result may be stratified by including the `by` argument. +#' +#' @param data (`data.frame`)\cr +#' a data frame. See below for details. +#' @param variables ([`tidy-select`][dplyr::dplyr_tidy_select])\cr +#' column names to be analyzed. Independent t-tests will be computed for +#' each variable. +#' @param by ([`tidy-select`][dplyr::dplyr_tidy_select])\cr +#' optional column name to stratify results by. +#' @inheritParams ard_stats_t_test +#' +#' @return ARD data frame +#' @export +#' +#' @examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom", reference_pkg = "cardx")) +#' cards::ADSL |> +#' ard_stats_t_test_onesample(by = ARM, variables = AGE) +ard_stats_t_test_onesample <- function(data, variables, by = dplyr::group_vars(data), conf.level = 0.95, ...) { + set_cli_abort_call() + + # check installed packages --------------------------------------------------- + check_pkg_installed("broom", reference_pkg = "cardx") + + # check/process inputs ------------------------------------------------------- + check_not_missing(data) + check_not_missing(variables) + check_data_frame(data) + data <- dplyr::ungroup(data) + cards::process_selectors(data, by = {{ by }}, variables = {{ variables }}) + check_scalar_range(conf.level, range = c(0, 1)) + + # if no variables selected, return empty tibble ------------------------------ + if (is_empty(variables)) { + return(dplyr::tibble()) + } + + cards::ard_continuous( + data = data, + variables = all_of(variables), + by = all_of(by), + statistic = all_of(variables) ~ list(t_test_onesample = \(x) stats::t.test(x = x, conf.level = conf.level, ...) |> broom::tidy()) + ) |> + cards::bind_ard( + cards::ard_continuous( + data = data, + variables = all_of(variables), + by = all_of(by), + statistic = + all_of(variables) ~ + list(conf.level = \(x) { + formals(asNamespace("stats")[["t.test.default"]])["mu"] |> + utils::modifyList(list(conf.level = conf.level, ...)) + }) + ) + ) |> + dplyr::select(-"stat_label") |> + dplyr::left_join( + .df_ttest_stat_labels(by = NULL), + by = "stat_name" + ) |> + dplyr::mutate( + stat_label = dplyr::coalesce(.data$stat_label, .data$stat_name), + context = "ard_stats_t_test_onesample", + ) |> + cards::tidy_ard_row_order() |> + cards::tidy_ard_column_order() +} diff --git a/R/ard_stats_wilcox_test_onesample.R b/R/ard_stats_wilcox_test_onesample.R new file mode 100644 index 000000000..7741c2cab --- /dev/null +++ b/R/ard_stats_wilcox_test_onesample.R @@ -0,0 +1,72 @@ +#' ARD one-sample Wilcox Rank-sum +#' +#' @description +#' Analysis results data for one-sample Wilcox Rank-sum. +#' Result may be stratified by including the `by` argument. +#' +#' @param data (`data.frame`)\cr +#' a data frame. See below for details. +#' @param variables ([`tidy-select`][dplyr::dplyr_tidy_select])\cr +#' column names to be analyzed. Independent Wilcox Rank-sum tests will be computed for +#' each variable. +#' @param by ([`tidy-select`][dplyr::dplyr_tidy_select])\cr +#' optional column name to stratify results by. +#' @inheritParams ard_stats_wilcox_test +#' +#' @return ARD data frame +#' @export +#' +#' @examplesIf do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom", reference_pkg = "cardx")) +#' cards::ADSL |> +#' ard_stats_wilcox_test_onesample(by = ARM, variables = AGE) +ard_stats_wilcox_test_onesample <- function(data, variables, by = dplyr::group_vars(data), conf.level = 0.95, ...) { + set_cli_abort_call() + + # check installed packages --------------------------------------------------- + check_pkg_installed("broom", reference_pkg = "cardx") + + # check/process inputs ------------------------------------------------------- + check_not_missing(data) + check_not_missing(variables) + check_data_frame(data) + data <- dplyr::ungroup(data) + cards::process_selectors(data, by = {{ by }}, variables = {{ variables }}) + check_scalar_range(conf.level, range = c(0, 1)) + + # if no variables selected, return empty tibble ------------------------------ + if (is_empty(variables)) { + return(dplyr::tibble()) + } + + cards::ard_continuous( + data = data, + variables = all_of(variables), + by = all_of(by), + statistic = all_of(variables) ~ list(t_test_onesample = \(x) stats::wilcox.test(x = x, conf.level = conf.level, ...) |> broom::tidy()) + ) |> + cards::bind_ard( + cards::ard_continuous( + data = data, + variables = all_of(variables), + by = all_of(by), + statistic = + all_of(variables) ~ + list(conf.level = \(x) { + formals(asNamespace("stats")[["wilcox.test.default"]])[c("mu", "exact", "conf.int", "tol.root", "digits.rank")] |> + utils::modifyList(list(conf.level = conf.level, ...)) |> + compact() + }) + ) + ) |> + dplyr::select(-"stat_label") |> + dplyr::left_join( + .df_ttest_stat_labels(by = NULL), + by = "stat_name" + ) |> + dplyr::mutate( + stat_label = dplyr::coalesce(.data$stat_label, .data$stat_name), + context = "ard_stats_wilcox_test_onesample", + ) |> + cards::tidy_ard_row_order() |> + cards::tidy_ard_column_order() +} diff --git a/README.Rmd b/README.Rmd index 8c2a55acf..0007ba337 100644 --- a/README.Rmd +++ b/README.Rmd @@ -5,7 +5,7 @@ editor_options: wrap: 72 --- -# cardx cardx website +# cardx cardx website [![R-CMD-check](https://github.com/insightsengineering/cardx/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/insightsengineering/cardx/actions/workflows/R-CMD-check.yaml) [![Codecov test diff --git a/README.md b/README.md index 7c108b27a..fda5d4cff 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# cardx cardx website +# cardx cardx website [![R-CMD-check](https://github.com/insightsengineering/cardx/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/insightsengineering/cardx/actions/workflows/R-CMD-check.yaml) [![Codecov test diff --git a/_pkgdown.yml b/_pkgdown.yml index 2e5965d2d..b40a3879f 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -34,7 +34,9 @@ reference: - ard_stats_oneway_test - ard_stats_prop_test - ard_stats_t_test + - ard_stats_t_test_onesample - ard_stats_wilcox_test + - ard_stats_wilcox_test_onesample - subtitle: "{aod} package" - contents: diff --git a/man/ard_stats_t_test_onesample.Rd b/man/ard_stats_t_test_onesample.Rd new file mode 100644 index 000000000..26a53a373 --- /dev/null +++ b/man/ard_stats_t_test_onesample.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ard_stats_t_test_onesample.R +\name{ard_stats_t_test_onesample} +\alias{ard_stats_t_test_onesample} +\title{ARD one-sample t-test} +\usage{ +ard_stats_t_test_onesample( + data, + variables, + by = dplyr::group_vars(data), + conf.level = 0.95, + ... +) +} +\arguments{ +\item{data}{(\code{data.frame})\cr +a data frame. See below for details.} + +\item{variables}{(\code{\link[dplyr:dplyr_tidy_select]{tidy-select}})\cr +column names to be analyzed. Independent t-tests will be computed for +each variable.} + +\item{by}{(\code{\link[dplyr:dplyr_tidy_select]{tidy-select}})\cr +optional column name to stratify results by.} + +\item{conf.level}{(scalar \code{numeric})\cr +confidence level for confidence interval. Default is \code{0.95}.} + +\item{...}{arguments passed to \code{t.test(...)}} +} +\value{ +ARD data frame +} +\description{ +Analysis results data for one-sample t-tests. +Result may be stratified by including the \code{by} argument. +} +\examples{ +\dontshow{if (do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom", reference_pkg = "cardx"))) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +cards::ADSL |> + ard_stats_t_test_onesample(by = ARM, variables = AGE) +\dontshow{\}) # examplesIf} +} diff --git a/man/ard_stats_wilcox_test_onesample.Rd b/man/ard_stats_wilcox_test_onesample.Rd new file mode 100644 index 000000000..b01882559 --- /dev/null +++ b/man/ard_stats_wilcox_test_onesample.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ard_stats_wilcox_test_onesample.R +\name{ard_stats_wilcox_test_onesample} +\alias{ard_stats_wilcox_test_onesample} +\title{ARD one-sample Wilcox Rank-sum} +\usage{ +ard_stats_wilcox_test_onesample( + data, + variables, + by = dplyr::group_vars(data), + conf.level = 0.95, + ... +) +} +\arguments{ +\item{data}{(\code{data.frame})\cr +a data frame. See below for details.} + +\item{variables}{(\code{\link[dplyr:dplyr_tidy_select]{tidy-select}})\cr +column names to be analyzed. Independent Wilcox Rank-sum tests will be computed for +each variable.} + +\item{by}{(\code{\link[dplyr:dplyr_tidy_select]{tidy-select}})\cr +optional column name to stratify results by.} + +\item{conf.level}{(scalar \code{numeric})\cr +confidence level for confidence interval. Default is \code{0.95}.} + +\item{...}{arguments passed to \code{wilcox.test(...)}} +} +\value{ +ARD data frame +} +\description{ +Analysis results data for one-sample Wilcox Rank-sum. +Result may be stratified by including the \code{by} argument. +} +\examples{ +\dontshow{if (do.call(asNamespace("cardx")$is_pkg_installed, list(pkg = "broom", reference_pkg = "cardx"))) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +cards::ADSL |> + ard_stats_wilcox_test_onesample(by = ARM, variables = AGE) +\dontshow{\}) # examplesIf} +} diff --git a/tests/testthat/test-ard_stats_t_test_onesample.R b/tests/testthat/test-ard_stats_t_test_onesample.R new file mode 100644 index 000000000..df62e11c2 --- /dev/null +++ b/tests/testthat/test-ard_stats_t_test_onesample.R @@ -0,0 +1,50 @@ +skip_if_not(is_pkg_installed("broom", reference_pkg = "cardx")) + +test_that("ard_stats_t_test_onesample() works", { + # first calculate an object to test against + expect_silent( + ard1 <- ard_stats_t_test_onesample( + cards::ADSL, + variables = AGE, + by = ARM, + conf.level = 0.9, + mu = 1 + ) + ) + + # first check arguments passed and returned correctly + expect_equal( + cards::get_ard_statistics( + ard1, + group1_level %in% "Placebo" + )[c("mu", "conf.level")], + list(mu = 1, conf.level = 0.9) + ) + # check results are correct + expect_equal( + cards::get_ard_statistics( + ard1, + group1_level %in% "Placebo" + )[c("estimate", "conf.low", "conf.high", "p.value")], + t.test( + cards::ADSL$AGE[cards::ADSL$ARM == "Placebo"], + conf.level = 0.9, + mu = 1 + ) |> + broom::tidy() |> + dplyr::select(c("estimate", "conf.low", "conf.high", "p.value")) |> + as.list() + ) + + # test the structure is good + expect_silent(cards::check_ard_structure(ard1)) + + # empty tibble returned with no variables + expect_equal( + ard_stats_t_test_onesample( + cards::ADSL, + variables = character(0) + ), + dplyr::tibble() + ) +}) diff --git a/tests/testthat/test-ard_stats_wilcox_test_onesample.R b/tests/testthat/test-ard_stats_wilcox_test_onesample.R new file mode 100644 index 000000000..3bd22c238 --- /dev/null +++ b/tests/testthat/test-ard_stats_wilcox_test_onesample.R @@ -0,0 +1,52 @@ +skip_if_not(is_pkg_installed("broom", reference_pkg = "cardx")) + +test_that("ard_stats_wilcox_test_onesample() works", { + # first calculate an object to test against + expect_silent( + ard1 <- ard_stats_wilcox_test_onesample( + cards::ADSL, + variables = AGE, + by = ARM, + conf.level = 0.9, + conf.int = TRUE, + mu = 1 + ) + ) + + # first check arguments passed and returned correctly + expect_equal( + cards::get_ard_statistics( + ard1, + group1_level %in% "Placebo" + )[c("mu", "conf.level")], + list(mu = 1, conf.level = 0.9) + ) + # check results are correct + expect_equal( + cards::get_ard_statistics( + ard1, + group1_level %in% "Placebo" + )[c("estimate", "conf.low", "conf.high", "p.value")], + wilcox.test( + cards::ADSL$AGE[cards::ADSL$ARM == "Placebo"], + conf.level = 0.9, + mu = 1, + conf.int = TRUE + ) |> + broom::tidy() |> + dplyr::select(c("estimate", "conf.low", "conf.high", "p.value")) |> + as.list() + ) + + # test the structure is good + expect_silent(cards::check_ard_structure(ard1)) + + # empty tibble returned with no variables + expect_equal( + ard_stats_wilcox_test_onesample( + cards::ADSL, + variables = character(0) + ), + dplyr::tibble() + ) +})