diff --git a/NAMESPACE b/NAMESPACE index 484e4f0..940bdac 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -15,3 +15,4 @@ export(median_diff) importFrom(ggplot2,.pt) importFrom(magrittr,"%>%") importFrom(rlang,.data) +importFrom(dplyr, n) diff --git a/R/001_api.R b/R/001_api.R index 0fd1b28..7176753 100644 --- a/R/001_api.R +++ b/R/001_api.R @@ -232,12 +232,19 @@ load <- function( ## Check to ensure control & treatment groups have the same sample size if is_paired is TRUE if (is_paired) { - if (length(unique(Ns$n)) > 1) { - cli::cli_abort(c("{.field data} is paired, as indicated by {.field paired} but size of control and treatment groups are not equal.", + for(i in idx) { + unlisted_pair <- unlist(i) + filter_df <- data %>% + dplyr::filter(!!enquo_x %in% unlisted_pair) + check_ns <- filter_df %>% + dplyr::count(!!enquo_x) + if (length(unique(check_ns$n)) > 1) { + cli::cli_abort(c("{.field data} is paired, as indicated by {.field paired} but size of control and treatment groups are not equal.", "x" = "Ensure that the size of control and treatment groups are the same for paired comparisons." )) } } +} # Extending ylim for plotting ylim[1] <- ylim[1] - (ylim[2] - ylim[1]) / 25 diff --git a/tests/testthat/test_001_api.R b/tests/testthat/test_001_api.R index fc61a29..8ffd0f6 100644 --- a/tests/testthat/test_001_api.R +++ b/tests/testthat/test_001_api.R @@ -1,3 +1,21 @@ +describe("Given non-valid params", { + # since this is more of an integration test, this unit test logic is repeated in test_001_utils.R + np_dataset <- generate_non_proportional_dataset() + p_dataset <- generate_proportional_dataset() + + # for paired data test + np_dataset_trunc <- np_dataset[-2, ] + + test_that("it should detect invalid x value", { + expect_error( + dabestr::load(np_dataset, + x = Grou, y = Measurement, + idx = c("Control 1", "Test 1") + ), + regexp = "Column x is not in data" + ) + }) + describe("Testing load function", { describe("Given valid params", { describe("Given non proportional dataset", { @@ -36,20 +54,7 @@ describe("Testing load function", { }) }) - describe("Given non-valid params", { - # since this is more of an integration test, this unit test logic is repeated in test_001_utils.R - np_dataset <- generate_non_proportional_dataset() - p_dataset <- generate_proportional_dataset() - test_that("it should detect invalid x value", { - expect_error( - dabestr::load(np_dataset, - x = Grou, y = Measurement, - idx = c("Control 1", "Test 1") - ), - regexp = "Column x is not in data" - ) - }) test_that("it should detect invalid y value", { expect_error( @@ -147,7 +152,7 @@ describe("Testing load function", { test_that("it should detect invalid dataset size", { expect_error( - dabestr::load(np_dataset[-2, ], + dabestr::load(np_dataset_trunc, x = Group, y = Measurement, idx = c("Control 1", "Test 1", "Test 2"), paired = "sequential", id_col = ID diff --git a/tests/testthat/test_001_utils.R b/tests/testthat/test_001_utils.R index d710453..eacc120 100644 --- a/tests/testthat/test_001_utils.R +++ b/tests/testthat/test_001_utils.R @@ -3,6 +3,9 @@ describe("Testing validate_load_params function", { np_dataset <- generate_non_proportional_dataset() p_dataset <- generate_proportional_dataset() + # for paired data test + np_dataset_trunc <- np_dataset[-2, ] + test_that("it should detect invalid x value", { expect_error( dabestr::load(np_dataset, @@ -109,7 +112,7 @@ describe("Testing validate_load_params function", { test_that("it should detect invalid dataset size", { expect_error( - dabestr::load(np_dataset[-2, ], + dabestr::load(np_dataset_trunc, x = Group, y = Measurement, idx = c("Control 1", "Test 1", "Test 2"), paired = "sequential", id_col = ID diff --git a/vignettes/.gitignore b/vignettes/.gitignore index 097b241..9e2bd63 100644 --- a/vignettes/.gitignore +++ b/vignettes/.gitignore @@ -1,2 +1,4 @@ *.html *.R + +/.quarto/ diff --git a/vignettes/plot_aesthetics.Rmd b/vignettes/plot_aesthetics.Rmd index e6174ba..b5cb20d 100644 --- a/vignettes/plot_aesthetics.Rmd +++ b/vignettes/plot_aesthetics.Rmd @@ -14,6 +14,7 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +library(dplyr) ``` Controlling plot aesthetics is straightforward in `dabestr`. A key feature of `dabestr` is the ability for users to freely customize various components of a `dabestr` estimation plot, allowing for the creation of an optimal-looking plot. diff --git a/vignettes/tutorial_basics.Rmd b/vignettes/tutorial_basics.Rmd index ecd20e6..7a84941 100644 --- a/vignettes/tutorial_basics.Rmd +++ b/vignettes/tutorial_basics.Rmd @@ -21,6 +21,7 @@ The dataset is first processed into the dabestr format using the `load()` functi ```{r setup, warning = FALSE, message = FALSE} library(dabestr) +library(dplyr) ``` ## Create dataset for demo diff --git a/vignettes/tutorial_deltadelta.Rmd b/vignettes/tutorial_deltadelta.Rmd index 0ccdef8..5d23e42 100644 --- a/vignettes/tutorial_deltadelta.Rmd +++ b/vignettes/tutorial_deltadelta.Rmd @@ -16,6 +16,7 @@ knitr::opts_chunk$set( ```{r, include = FALSE, warning = FALSE, message = FALSE} library(dabestr) +library(dplyr) ``` This vignette documents how `dabestr` is able to compute the calculation of delta-delta, an experimental function that allows the comparison between two bootstrapped effect sizes computed from two independent categorical variables. diff --git a/vignettes/tutorial_minimeta.Rmd b/vignettes/tutorial_minimeta.Rmd index 87aa554..0072867 100644 --- a/vignettes/tutorial_minimeta.Rmd +++ b/vignettes/tutorial_minimeta.Rmd @@ -33,6 +33,7 @@ For more information on meta-analysis, please refer to [Chapter 10](https://trai ```{r setup, warning = FALSE, message = FALSE} library(dabestr) +library(dplyr) ``` ## Create dataset for demo diff --git a/vignettes/tutorial_proportion_plots.Rmd b/vignettes/tutorial_proportion_plots.Rmd index 2d9f8bd..daf7f16 100644 --- a/vignettes/tutorial_proportion_plots.Rmd +++ b/vignettes/tutorial_proportion_plots.Rmd @@ -24,6 +24,7 @@ This vignette documents how the `dabestr` package is able to generate proportion ```{r setup, warning = FALSE, message = FALSE} library(dabestr) +library(dplyr) ``` ## Create dataset for demo diff --git a/vignettes/tutorial_repeated_measures.Rmd b/vignettes/tutorial_repeated_measures.Rmd index 4a59b5e..7c41256 100644 --- a/vignettes/tutorial_repeated_measures.Rmd +++ b/vignettes/tutorial_repeated_measures.Rmd @@ -25,6 +25,7 @@ To use these features, simply declare the `paired` argument as either "sequentia ```{r setup, warning = FALSE, message = FALSE} library(dabestr) +library(dplyr) ``` ## Create dataset for demo @@ -221,3 +222,52 @@ dabest_plot(multi_baseline_repeated_measures.mean_diff, raw_marker_size = 0.5, raw_marker_alpha = 0.3 ) ``` + +## Paired groups with different sample sizes across comparisons + +Repeated-measures plots also work when different comparison pairs have different sample sizes, as long as each pair is internally balanced. + +```{r} +set.seed(12345) +N1 <- 20 +N2 <- 10 + +df_unequal_pairs <- tibble::tibble( + Group = rep(c("Control 1", "Test 1", "Control 2", "Test 2"), c(N1, N1, N2, N2)), + Measurement = c( + rnorm(N1, mean = 3, sd = 0.4), # Control 1 + rnorm(N1, mean = 3.5, sd = 0.5), # Test 1 + rnorm(N2, mean = 2.5, sd = 0.4), # Control 2 + rnorm(N2, mean = 3.0, sd = 0.5) # Test 2 + ), + ID = c(1:N1, 1:N1, 1:N2, 1:N2) +) +``` + +```{r, warning = FALSE} +# Each pair is internally balanced even though the two pairs differ in size. +multi_unequal_pairs.mean_diff <- load(df_unequal_pairs, + x = Group, y = Measurement, + idx = list(c("Control 1", "Test 1"), c("Control 2", "Test 2")), + paired = "sequential", id_col = ID +) %>% + mean_diff() + +dabest_plot(multi_unequal_pairs.mean_diff, + raw_marker_size = 0.5, raw_marker_alpha = 0.3 +) +``` + +An unbalanced pair (different n *within* a pair) is still caught as an error: + +```{r, error = TRUE} +# Remove one row from Test 1 so Control 1 (n=20) and Test 1 (n=19) are mismatched within the pair. +df_bad_pair <- df_unequal_pairs %>% + dplyr::filter(!(Group == "Test 1" & ID == 1)) + +load(df_bad_pair, + x = Group, y = Measurement, + idx = list(c("Control 1", "Test 1"), c("Control 2", "Test 2")), + paired = "sequential", id_col = ID +) +``` \ No newline at end of file