diff --git a/DESCRIPTION b/DESCRIPTION index 4ad79bd..218a7e3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: ISCAM Title: Companion to the Book "Investigating Statistical Concepts, Applications, and Methods" -Version: 0.0.0.9000 +Version: 0.1.0 Authors@R: c( person("Beth", "Chance", , "bchance@calpoly.edu", role = c("cre", "aut", "cph")), person("Visruth", "Srimath Kandali", , "visruth@gmail.com", role = "aut", @@ -34,4 +34,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 diff --git a/tests/testthat/_snaps/binomial-suite.md b/tests/testthat/_snaps/binomial-suite.md new file mode 100644 index 0000000..10af668 --- /dev/null +++ b/tests/testthat/_snaps/binomial-suite.md @@ -0,0 +1,69 @@ +# iscambinomprob returns expected tail probabilities + + Code + res_lower$output + Output + [1] "Probability 3 and below = 0.3822806 " + +--- + + Code + res_upper$output + Output + [1] "Probability 7 and above = 0.05476188 " + +# iscaminvbinom solves the correct quantile + + Code + res_lower$output + Output + [1] "The observation with at most 0.1 probability at or below is 4 " + +--- + + Code + res_upper$output + Output + [1] "The observation with at most 0.1 probability at or above is 12 " + +# iscambinomnorm executes for each direction + + Code + capture_plot_result(iscambinomnorm(10, 20, 0.5, "below"))$output + Output + [1] " binomial: 0.5881 " + [2] " normal approx: 0.5 " + [3] " normal approx with continuity: 0.5885 " + +--- + + Code + capture_plot_result(iscambinomnorm(10, 20, 0.5, "above"))$output + Output + [1] " binomial: 0.5881 " + [2] " normal approx: 0.5 " + [3] " normal approx with continuity: 0.5885 " + +# iscambinompower reports rejection probabilities + + Code + res$output + Output + [1] "Null: Probability 15 and above = 0.02069473 " + [2] "Alternative: Probability 15 and above = 0.125599 " + +# iscambinomtest matches binom.test results + + Code + res$output + Output + [1] "" + [2] "Exact Binomial Test" + [3] "" + [4] "Data: observed successes = 18, sample size = 30, sample proportion = 0.6" + [5] "" + [6] "Null hypothesis : pi = 0.5 " + [7] "Alternative hypothesis: pi <> 0.5 " + [8] "p-value: 0.36159 " + [9] "95 % Confidence interval for pi: ( 0.40603 , 0.77344 ) " + diff --git a/tests/testthat/_snaps/chisq-hyper.md b/tests/testthat/_snaps/chisq-hyper.md new file mode 100644 index 0000000..8ac671e --- /dev/null +++ b/tests/testthat/_snaps/chisq-hyper.md @@ -0,0 +1,39 @@ +# iscamchisqprob returns formatted upper-tail probability + + Code + res$output + Output + [1] "probability: 0.1718 " + +# iscamhyperprob matches hypergeometric tails + + Code + res_lower$output + Output + [1] "Probability 2 and below = 0.7038184 " + +--- + + Code + res_upper$output + Output + [1] "Probability 3 and above = 0.2961816 " + +# iscamhypernorm reports tail probabilities and normal approximations + + Code + res_lower$output + Output + [1] " hypergeometric: 0.7038 " + [2] " normal approx: 0.5 " + [3] " normal approx with continuity: 0.6963 " + +--- + + Code + res_upper$output + Output + [1] " hypergeometric: 0.2962 " + [2] " normal approx: 0.1521 " + [3] " normal approx with continuity: 0.3037 " + diff --git a/tests/testthat/_snaps/iscamsummary.md b/tests/testthat/_snaps/iscamsummary.md deleted file mode 100644 index b4e3bcc..0000000 --- a/tests/testthat/_snaps/iscamsummary.md +++ /dev/null @@ -1,37 +0,0 @@ -# summary without explanatory works - - Code - iscamsummary(fake_data) - Output - Missing n Min Q1 Median Q3 Max Mean SD Skewness - 1 0 30 -1.54 -0.621 -0.031 0.487 2.405 0.022 0.914 0.441 - ---- - - Code - iscamsummary(fake_data, digits = 5) - Output - Missing n Min Q1 Median Q3 Max Mean SD - 1 0 30 -1.53995 -0.62109 -0.03144 0.48663 2.40465 0.02195 0.91414 - Skewness - 1 0.44133 - -# summary with explanatory works - - Code - iscamsummary(fake_data, groups) - Output - Missing n Min Q1 Median Q3 Max Mean SD Skewness - group1 0 13 -1.238 -0.326 -0.057 0.436 1.263 -0.020 0.655 0.210 - group2 0 17 -1.540 -0.892 0.133 0.764 2.405 0.054 1.091 0.384 - ---- - - Code - iscamsummary(fake_data, groups) - Output - Missing n Min Q1 Median Q3 Max Mean SD Skewness - group1 0 10 -1.540 -0.298 -0.148 0.676 2.405 0.173 1.103 0.582 - group2 0 10 -1.285 -1.093 -0.089 0.360 1.330 -0.207 0.919 0.217 - group3 0 10 -0.892 -0.390 0.098 0.472 1.272 0.101 0.736 0.216 - diff --git a/tests/testthat/_snaps/normal-suite.md b/tests/testthat/_snaps/normal-suite.md new file mode 100644 index 0000000..6374734 --- /dev/null +++ b/tests/testthat/_snaps/normal-suite.md @@ -0,0 +1,36 @@ +# iscamnormprob returns formatted probabilities + + Code + res_above$output + Output + [1] "probability: 0.025 " + +--- + + Code + res_between$output + Output + [1] "probability: 0.6827 " + +# iscamnormpower reports null and alternative rejection rates + + Code + res$output + Output + [1] "Null: Probability 0.592 and above = 0.05 " + [2] "Alt: Probability 0.592 and above = 0.2253625 " + +# iscaminvnorm reports requested quantiles + + Code + res_below$output + Output + [1] "The observation with 0.05 probability below is -1.645 " + +--- + + Code + res_outside$output + Output + [1] "There is 0.1 probability outside -1.645 and 1.645 " + diff --git a/tests/testthat/_snaps/overlayDensities/addt-plot.svg b/tests/testthat/_snaps/overlayDensities/addt-plot.svg deleted file mode 100644 index 68480c3..0000000 --- a/tests/testthat/_snaps/overlayDensities/addt-plot.svg +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - --2 --1 -0 -1 -2 - - - - - - - -0.0 -0.1 -0.2 -0.3 -0.4 -0.5 - - - - - - - - - - - - - - - - - - - - -x -density -Histogram with t curve - - diff --git a/tests/testthat/_snaps/overlayDensities/addtnorm-plot.svg b/tests/testthat/_snaps/overlayDensities/addtnorm-plot.svg deleted file mode 100644 index 3f866b0..0000000 --- a/tests/testthat/_snaps/overlayDensities/addtnorm-plot.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - --4 --2 -0 -2 - - - - - - -0.0 -0.1 -0.2 -0.3 -0.4 - - - - - - - - - - - - - - - - - - - - - - -x -density -Histogram with t and normal curve - - - - - -normal -t, df=5 - - diff --git a/tests/testthat/_snaps/overlayDensities/custom-parameters-plot.svg b/tests/testthat/_snaps/overlayDensities/custom-params.svg similarity index 99% rename from tests/testthat/_snaps/overlayDensities/custom-parameters-plot.svg rename to tests/testthat/_snaps/overlayDensities/custom-params.svg index 8a4bc55..3f8bad9 100644 --- a/tests/testthat/_snaps/overlayDensities/custom-parameters-plot.svg +++ b/tests/testthat/_snaps/overlayDensities/custom-params.svg @@ -1,87 +1,87 @@ - - - - - - - - - - - - - - - - - - --2 --1 -0 -1 -2 - - - - - - - - -0.0 -0.1 -0.2 -0.3 -0.4 -0.5 -0.6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -My Data -density -Custom Title - - + + + + + + + + + + + + + + + + + + +-2 +-1 +0 +1 +2 + + + + + + + + +0.0 +0.1 +0.2 +0.3 +0.4 +0.5 +0.6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +My Data +density +Custom Title + + diff --git a/tests/testthat/_snaps/overlayDensities/addexp-plot.svg b/tests/testthat/_snaps/overlayDensities/exponential.svg similarity index 99% rename from tests/testthat/_snaps/overlayDensities/addexp-plot.svg rename to tests/testthat/_snaps/overlayDensities/exponential.svg index 5db6b70..636e5c4 100644 --- a/tests/testthat/_snaps/overlayDensities/addexp-plot.svg +++ b/tests/testthat/_snaps/overlayDensities/exponential.svg @@ -1,65 +1,65 @@ - - - - - - - - - - - - - - - - - - - -0.0 -0.5 -1.0 -1.5 -2.0 -2.5 - - - - - - -0.0 -0.5 -1.0 -1.5 -2.0 - - - - - - - - - - - - - - - - -x -density -Histogram with exponential curve - - + + + + + + + + + + + + + + + + + + + +0.0 +0.5 +1.0 +1.5 +2.0 +2.5 + + + + + + +0.0 +0.5 +1.0 +1.5 +2.0 + + + + + + + + + + + + + + + + +generate_data(dist = "exp", rate = 2) +density +Histogram with exponential curve + + diff --git a/tests/testthat/_snaps/overlayDensities/addlnorm-plot.svg b/tests/testthat/_snaps/overlayDensities/log-normal.svg similarity index 99% rename from tests/testthat/_snaps/overlayDensities/addlnorm-plot.svg rename to tests/testthat/_snaps/overlayDensities/log-normal.svg index 3b8e2fd..e5ec3ce 100644 --- a/tests/testthat/_snaps/overlayDensities/addlnorm-plot.svg +++ b/tests/testthat/_snaps/overlayDensities/log-normal.svg @@ -1,72 +1,72 @@ - - - - - - - - - - - - - - - - - - - -0 -2 -4 -6 -8 -10 - - - - - - - - - -0.0 -0.1 -0.2 -0.3 -0.4 -0.5 -0.6 -0.7 - - - - - - - - - - - - - - - - - -x -density -Histogram with log-normal curve - - + + + + + + + + + + + + + + + + + + + +0 +2 +4 +6 +8 +10 + + + + + + + + + +0.0 +0.1 +0.2 +0.3 +0.4 +0.5 +0.6 +0.7 + + + + + + + + + + + + + + + + + +generate_data(dist = "lnorm") +density +Histogram with log-normal curve + + diff --git a/tests/testthat/_snaps/overlayDensities/addnorm-plot.svg b/tests/testthat/_snaps/overlayDensities/normal-plot.svg similarity index 99% rename from tests/testthat/_snaps/overlayDensities/addnorm-plot.svg rename to tests/testthat/_snaps/overlayDensities/normal-plot.svg index 79dda94..a606938 100644 --- a/tests/testthat/_snaps/overlayDensities/addnorm-plot.svg +++ b/tests/testthat/_snaps/overlayDensities/normal-plot.svg @@ -1,70 +1,70 @@ - - - - - - - - - - - - - - - - - - --2 --1 -0 -1 -2 - - - - - - - -0.0 -0.1 -0.2 -0.3 -0.4 -0.5 - - - - - - - - - - - - - - - - - - - - - -x -density -Histogram with normal curve - - + + + + + + + + + + + + + + + + + + +-2 +-1 +0 +1 +2 + + + + + + + +0.0 +0.1 +0.2 +0.3 +0.4 +0.5 + + + + + + + + + + + + + + + + + + + + + +generate_data(dist = "norm") +density +Histogram with normal curve + + diff --git a/tests/testthat/_snaps/overlayDensities/t-and-normal.svg b/tests/testthat/_snaps/overlayDensities/t-and-normal.svg new file mode 100644 index 0000000..cf734af --- /dev/null +++ b/tests/testthat/_snaps/overlayDensities/t-and-normal.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + +-15 +-10 +-5 +0 +5 +10 +15 + + + + + + + + +0.00 +0.02 +0.04 +0.06 +0.08 +0.10 +0.12 + + + + + + + + + + + + + + + + + + + + + +generate_data(dist = "t", df = 1) +density +Histogram with t and normal curve + + + + + +normal +t, df=1 + + diff --git a/tests/testthat/_snaps/overlayDensities/t-distribution.svg b/tests/testthat/_snaps/overlayDensities/t-distribution.svg new file mode 100644 index 0000000..032091d --- /dev/null +++ b/tests/testthat/_snaps/overlayDensities/t-distribution.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + +-2 +-1 +0 +1 +2 + + + + + + + +0.0 +0.1 +0.2 +0.3 +0.4 +0.5 + + + + + + + + + + + + + + + + + + + + +generate_data(dist = "t", df = 15) +density +Histogram with t curve + + diff --git a/tests/testthat/_snaps/plots/boxplot-one-var.svg b/tests/testthat/_snaps/plots/iscamboxplot-one-variable.svg similarity index 94% rename from tests/testthat/_snaps/plots/boxplot-one-var.svg rename to tests/testthat/_snaps/plots/iscamboxplot-one-variable.svg index d84e3da..3ee8a42 100644 --- a/tests/testthat/_snaps/plots/boxplot-one-var.svg +++ b/tests/testthat/_snaps/plots/iscamboxplot-one-variable.svg @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -10 -15 -20 -25 -30 - -mtcars Cylinders Dotplot -Number of Cylinders - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +10 +15 +20 +25 +30 + +mtcars Cylinders iscamdotplot +Number of Cylinders + + diff --git a/tests/testthat/_snaps/plots/boxplot-two-vars.svg b/tests/testthat/_snaps/plots/iscamboxplot-two-variables.svg similarity index 98% rename from tests/testthat/_snaps/plots/boxplot-two-vars.svg rename to tests/testthat/_snaps/plots/iscamboxplot-two-variables.svg index fc2a9d9..6e4d4a5 100644 --- a/tests/testthat/_snaps/plots/boxplot-two-vars.svg +++ b/tests/testthat/_snaps/plots/iscamboxplot-two-variables.svg @@ -1,65 +1,65 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 -1 - - - - - - -10 -15 -20 -25 -30 - -Automatic Cars Have Better Mileage on Average -Mileage (miles per gallon) -Automatic (yes coded as 1) - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0 +1 + + + + + + +10 +15 +20 +25 +30 + +Automatic Cars Have Better Mileage on Average +Mileage (miles per gallon) +Automatic (yes coded as 1) + + diff --git a/tests/testthat/_snaps/plots/dotplot-one-var.svg b/tests/testthat/_snaps/plots/iscamdotplot-one-variable.svg similarity index 96% rename from tests/testthat/_snaps/plots/dotplot-one-var.svg rename to tests/testthat/_snaps/plots/iscamdotplot-one-variable.svg index 99fe84e..3838c88 100644 --- a/tests/testthat/_snaps/plots/dotplot-one-var.svg +++ b/tests/testthat/_snaps/plots/iscamdotplot-one-variable.svg @@ -1,78 +1,78 @@ - - - - - - - - - - - - - - - - - - - -4 -5 -6 -7 -8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -mtcars Cylinders Dotplot -Number of Cylinders - - + + + + + + + + + + + + + + + + + + + +4 +5 +6 +7 +8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +mtcars Cylinders iscamdotplot +Number of Cylinders + + diff --git a/tests/testthat/_snaps/plots/dotplot-two-vars.svg b/tests/testthat/_snaps/plots/iscamdotplot-two-variables.svg similarity index 98% rename from tests/testthat/_snaps/plots/dotplot-two-vars.svg rename to tests/testthat/_snaps/plots/iscamdotplot-two-variables.svg index c218074..feef04e 100644 --- a/tests/testthat/_snaps/plots/dotplot-two-vars.svg +++ b/tests/testthat/_snaps/plots/iscamdotplot-two-variables.svg @@ -1,85 +1,85 @@ - - - - - - - - - - - - - - - - - - - -10 -15 -20 -25 -30 - - - -0 -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Automatic Cars Have Better Mileage on Average -Mileage (miles per gallon) -Automatic (yes coded as 1) - - + + + + + + + + + + + + + + + + + + + +10 +15 +20 +25 +30 + + + +0 +1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Automatic Cars Have Better Mileage on Average +Mileage (miles per gallon) +Automatic (yes coded as 1) + + diff --git a/tests/testthat/_snaps/prop-tests.md b/tests/testthat/_snaps/prop-tests.md new file mode 100644 index 0000000..8649ad5 --- /dev/null +++ b/tests/testthat/_snaps/prop-tests.md @@ -0,0 +1,34 @@ +# iscamonepropztest agrees with prop.test + + Code + res$output + Output + [1] "" + [2] "One Proportion z test" + [3] "" + [4] "Data: observed successes = 35, sample size = 50, sample proportion = 0.7" + [5] "" + [6] "Null hypothesis : pi = 0.5 " + [7] "Alternative hypothesis: pi > 0.5 " + [8] "z-statistic: 2.828 " + [9] "p-value: 0.002339 " + [10] "95 % Confidence interval for pi: ( 0.5729798 , 0.8270202 ) " + +# iscamtwopropztest matches two-sample z test calculations + + Code + res$output + Output + [1] "" + [2] "Two Proportion z test" + [3] "" + [4] "Group1: observed successes = 35, sample size = 50, sample proportion = 0.7" + [5] "" + [6] "Group2: observed successes = 28, sample size = 45, sample proportion = 0.6222" + [7] "" + [8] "Null hypothesis : pi1-pi2 = 0 " + [9] "Alternative hypothesis: pi1-pi2 > 0 " + [10] "z-statistic: 0.8009 " + [11] "95 % Confidence interval for pi1-pi2: ( -0.1124861 , 0.2680417 ) " + [12] "p-value: 0.2116 " + diff --git a/tests/testthat/_snaps/t-suite.md b/tests/testthat/_snaps/t-suite.md new file mode 100644 index 0000000..701401e --- /dev/null +++ b/tests/testthat/_snaps/t-suite.md @@ -0,0 +1,48 @@ +# iscamtprob matches t tail probabilities + + Code + res_below$output + Output + [1] "probability: 0.03375 " + +--- + + Code + res_between$output + Output + [1] "probability: 0.9313 " + +# iscamonesamplet returns Welch statistics + + Code + res$output + Output + [1] "" + [2] "One Sample t test" + [3] "" + [4] "mean = 2.5, sd = 1.2, sample size = 30" + [5] "Null hypothesis : mu = 2 " + [6] "Alternative hypothesis: mu > 2 " + [7] "t-statistic: 2.282 " + [8] "95 % Confidence interval for mu: ( 2.051913 , 2.948087 ) " + [9] "p-value: 0.01499991 " + +# iscamtwosamplet returns Welch two-sample results + + Code + res$output + Output + [1] "" + [2] "Two Sample t test" + [3] "" + [4] "Group1: mean = 5, sd = 2, sample size = 30" + [5] "Group2: mean = 4, sd = 1.5, sample size = 28" + [6] "diff:1" + [7] "" + [8] "Null hypothesis : mu1-mu2 = 0 " + [9] "Alternative hypothesis: mu1-mu2 <> 0 " + [10] "t-statistic: 2.163 " + [11] "df: 53.58 " + [12] "95 % Confidence interval for mu1-mu2: ( 0.07304471 , 1.926955 ) " + [13] "p-value: 0.035 " + diff --git a/tests/testthat/helper-capture.R b/tests/testthat/helper-capture.R new file mode 100644 index 0000000..0c7a71b --- /dev/null +++ b/tests/testthat/helper-capture.R @@ -0,0 +1,20 @@ +capture_plot_result <- function(expr) { + tmp <- tempfile(fileext = ".pdf") + grDevices::pdf(tmp) + on.exit( + { + grDevices::dev.off() + unlink(tmp) + }, + add = TRUE + ) + value <- NULL + output <- capture.output({ + value <- withVisible(force(expr)) + }) + list(output = output, value = value$value, visible = value$visible) +} + +collapse_output <- function(lines) { + paste(lines, collapse = "\n") +} diff --git a/tests/testthat/test-binomial-suite.R b/tests/testthat/test-binomial-suite.R new file mode 100644 index 0000000..597526f --- /dev/null +++ b/tests/testthat/test-binomial-suite.R @@ -0,0 +1,93 @@ +test_that("iscambinomprob returns expected tail probabilities", { + res_lower <- capture_plot_result(iscambinomprob( + k = 3, + n = 10, + prob = 0.4, + lower.tail = TRUE + )) + res_upper <- capture_plot_result(iscambinomprob( + k = 7, + n = 10, + prob = 0.4, + lower.tail = FALSE + )) + + expect_equal(res_lower$value, pbinom(3, 10, 0.4), tolerance = 1e-6) + expect_equal(res_upper$value, 1 - pbinom(6, 10, 0.4), tolerance = 1e-6) + + expect_snapshot(res_lower$output) + expect_snapshot(res_upper$output) +}) + +test_that("iscaminvbinom solves the correct quantile", { + res_lower <- capture_plot_result(iscaminvbinom( + alpha = 0.1, + n = 20, + prob = 0.4, + lower.tail = TRUE + )) + res_upper <- capture_plot_result(iscaminvbinom( + alpha = 0.1, + n = 20, + prob = 0.4, + lower.tail = FALSE + )) + + expect_equal(res_lower$value, qbinom(0.1, 20, 0.4, lower.tail = TRUE) - 1) + expect_equal(res_upper$value, qbinom(0.1, 20, 0.4, lower.tail = FALSE) + 1) + + expect_snapshot(res_lower$output) + expect_snapshot(res_upper$output) +}) + +test_that("iscambinomnorm executes for each direction", { + expect_snapshot( + capture_plot_result(iscambinomnorm(10, 20, 0.5, "below"))$output + ) + expect_snapshot( + capture_plot_result(iscambinomnorm(10, 20, 0.5, "above"))$output + ) +}) + +test_that("iscambinompower reports rejection probabilities", { + los <- 0.05 + n <- 20 + prob1 <- 0.5 + prob2 <- 0.6 + + res <- capture_plot_result(suppressWarnings(iscambinompower( + LOS = los, + n = n, + prob1 = prob1, + alternative = "greater", + prob2 = prob2 + ))) + rr <- qbinom(los, n, prob1, lower.tail = FALSE) + 1 + null_prob <- 1 - pbinom(rr - 1, n, prob1) + alt_prob <- 1 - pbinom(rr - 1, n, prob2) + + expect_equal(rr, 15) + expect_equal(null_prob, 0.02069473, tolerance = 1e-6) + expect_equal(alt_prob, 0.125599, tolerance = 1e-6) + expect_null(res$value) + + expect_snapshot(res$output) +}) + +test_that("iscambinomtest matches binom.test results", { + res <- capture_plot_result(iscambinomtest( + observed = 18, + n = 30, + hypothesized = 0.5, + alternative = "two.sided", + conf.level = 0.95 + )) + + bt <- binom.test(18, 30, p = 0.5, alternative = "two.sided") + + expect_equal(res$value$pvalue, signif(bt$p.value, 5), tolerance = 1e-6) + expect_equal(res$value$lower, bt$conf.int[1], tolerance = 1e-4) + expect_equal(res$value$upper, bt$conf.int[2], tolerance = 1e-4) + + expect_snapshot(res$output) +}) diff --git a/tests/testthat/test-chisq-hyper.R b/tests/testthat/test-chisq-hyper.R new file mode 100644 index 0000000..1da0272 --- /dev/null +++ b/tests/testthat/test-chisq-hyper.R @@ -0,0 +1,59 @@ +test_that("iscamchisqprob returns formatted upper-tail probability", { + res <- capture_plot_result(iscamchisqprob(5, 3)) + + expect_equal( + as.numeric(res$value), + pchisq(5, 3, lower.tail = FALSE), + tolerance = 1e-4 + ) + + expect_snapshot(res$output) +}) + +test_that("iscamhyperprob matches hypergeometric tails", { + res_lower <- capture_plot_result(suppressWarnings(iscamhyperprob( + k = 2, + total = 20, + succ = 5, + n = 8, + lower.tail = TRUE + ))) + res_upper <- capture_plot_result(suppressWarnings(iscamhyperprob( + k = 3, + total = 20, + succ = 5, + n = 8, + lower.tail = FALSE + ))) + + fail <- 20 - 5 + + expect_equal(res_lower$value, phyper(2, 5, fail, 8), tolerance = 1e-6) + expect_equal(res_upper$value, 1 - phyper(2, 5, fail, 8), tolerance = 1e-6) + + expect_snapshot(res_lower$output) + expect_snapshot(res_upper$output) +}) + +test_that("iscamhypernorm reports tail probabilities and normal approximations", { + res_lower <- capture_plot_result(suppressWarnings(iscamhypernorm( + k = 2, + total = 20, + succ = 5, + n = 8, + lower.tail = TRUE + ))) + res_upper <- capture_plot_result(suppressWarnings(iscamhypernorm( + k = 3, + total = 20, + succ = 5, + n = 8, + lower.tail = FALSE + ))) + + expect_null(res_lower$value) + expect_null(res_upper$value) + + expect_snapshot(res_lower$output) + expect_snapshot(res_upper$output) +}) diff --git a/tests/testthat/test-iscamsummary.R b/tests/testthat/test-iscamsummary.R index 94d9ba8..fe39721 100644 --- a/tests/testthat/test-iscamsummary.R +++ b/tests/testthat/test-iscamsummary.R @@ -17,7 +17,6 @@ raw_summary <- data.frame( row.names = NULL ) - test_that("summary without explanatory works", { expect_equal( iscamsummary(fake_data), @@ -28,9 +27,6 @@ test_that("summary without explanatory works", { iscamsummary(fake_data, digits = 5), raw_summary |> round(5) ) - - expect_snapshot(iscamsummary(fake_data)) - expect_snapshot(iscamsummary(fake_data, digits = 5)) }) test_that("summary with explanatory works", { @@ -42,8 +38,6 @@ test_that("summary with explanatory works", { rbind(iscamsummary(group1), iscamsummary(group2)) |> structure(row.names = c("group1", "group2")) ) - expect_snapshot(iscamsummary(fake_data, groups)) - groups <- sample(c("group1", "group2", "group3"), 30, TRUE) group1 <- fake_data[groups == "group1"] group2 <- fake_data[groups == "group2"] @@ -54,5 +48,4 @@ test_that("summary with explanatory works", { rbind(iscamsummary(group1), iscamsummary(group2), iscamsummary(group3)) |> structure(row.names = c("group1", "group2", "group3")) ) - expect_snapshot(iscamsummary(fake_data, groups)) }) diff --git a/tests/testthat/test-normal-suite.R b/tests/testthat/test-normal-suite.R new file mode 100644 index 0000000..b769e1e --- /dev/null +++ b/tests/testthat/test-normal-suite.R @@ -0,0 +1,73 @@ +test_that("iscamnormprob returns formatted probabilities", { + res_above <- capture_plot_result(suppressWarnings(iscamnormprob( + 1.96, + direction = "above" + ))) + res_between <- capture_plot_result(suppressWarnings(iscamnormprob( + -1, + xval2 = 1, + direction = "between" + ))) + + expect_equal( + as.numeric(res_above$value), + round(pnorm(1.96, lower.tail = FALSE), 3), + tolerance = 1e-6 + ) + expect_equal( + as.numeric(res_between$value), + round(pnorm(1) - pnorm(-1), 4), + tolerance = 1e-6 + ) + + expect_snapshot(res_above$output) + expect_snapshot(res_between$output) +}) + +test_that("iscamnormpower reports null and alternative rejection rates", { + los <- 0.05 + n <- 80 + prob1 <- 0.5 + prob2 <- 0.55 + + res <- capture_plot_result(suppressWarnings(iscamnormpower( + LOS = los, + n = n, + prob1 = prob1, + alternative = "greater", + prob2 = prob2 + ))) + + mean1 <- prob1 + sd1 <- sqrt(prob1 * (1 - prob1) / n) + rr <- qnorm(los, mean1, sd1, lower.tail = FALSE) + null_prob <- 1 - pnorm(rr, mean1, sd1) + + mean2 <- prob2 + sd2 <- sqrt(prob2 * (1 - prob2) / n) + alt_prob <- 1 - pnorm(rr, mean2, sd2) + + expect_equal(rr, 0.5919501, tolerance = 1e-6) + expect_equal(null_prob, 0.05, tolerance = 1e-7) + expect_equal(alt_prob, 0.2253625, tolerance = 1e-7) + expect_null(res$value) + + expect_snapshot(res$output) +}) + +test_that("iscaminvnorm reports requested quantiles", { + res_below <- capture_plot_result(suppressWarnings(iscaminvnorm( + 0.05, + direction = "below" + ))) + res_outside <- capture_plot_result(suppressWarnings(iscaminvnorm( + 0.1, + direction = "outside" + ))) + + expect_null(res_below$value) + expect_null(res_outside$value) + + expect_snapshot(res_below$output) + expect_snapshot(res_outside$output) +}) diff --git a/tests/testthat/test-overlayDensities.R b/tests/testthat/test-overlayDensities.R index 988db8c..d9d5251 100644 --- a/tests/testthat/test-overlayDensities.R +++ b/tests/testthat/test-overlayDensities.R @@ -11,40 +11,51 @@ generate_data <- function(n = 100, dist = c("norm", "exp", "lnorm", "t"), ...) { } test_that("iscamaddexp creates an exponential plot", { - x <- generate_data(dist = "exp", rate = 2) - vdiffr::expect_doppelganger("iscamaddexp plot", function() iscamaddexp(x)) + vdiffr::expect_doppelganger("exponential", function() { + iscamaddexp(generate_data( + dist = "exp", + rate = 2 + )) + }) }) test_that("iscamaddlnorm creates a log-normal plot", { - x <- generate_data(dist = "lnorm") - vdiffr::expect_doppelganger("iscamaddlnorm plot", function() iscamaddlnorm(x)) + vdiffr::expect_doppelganger("log-normal", function() { + iscamaddlnorm(generate_data(dist = "lnorm")) + }) }) test_that("iscamaddnorm creates a normal plot", { - x <- generate_data(dist = "norm") - vdiffr::expect_doppelganger("iscamaddnorm plot", function() iscamaddnorm(x)) + vdiffr::expect_doppelganger("Normal plot", function() { + iscamaddnorm(generate_data(dist = "norm")) + }) }) test_that("iscamaddt creates a t-distribution plot", { - x <- generate_data(dist = "t", df = 15) - vdiffr::expect_doppelganger("iscamaddt plot", function() { - iscamaddt(x, df = 10) + vdiffr::expect_doppelganger("t-distribution", function() { + iscamaddt( + generate_data(dist = "t", df = 15), + df = 15 + ) }) }) test_that("iscamaddtnorm creates a t and normal plot", { - x <- generate_data(dist = "t", df = 5) - vdiffr::expect_doppelganger("iscamaddtnorm plot", function() { - iscamaddtnorm(x, df = 5) + vdiffr::expect_doppelganger("t and normal", function() { + iscamaddtnorm( + generate_data(dist = "t", df = 1), + df = 1 + ) }) }) test_that("Plotting with custom parameters works", { - x <- generate_data(dist = "norm") - vdiffr::expect_doppelganger( - "Custom parameters plot", - function() { - iscamaddnorm(x, main = "Custom Title", xlab = "My Data", bins = 20) - } - ) + vdiffr::expect_doppelganger("Custom params", function() { + iscamaddnorm( + generate_data(dist = "norm"), + main = "Custom Title", + xlab = "My Data", + bins = 20 + ) + }) }) diff --git a/tests/testthat/test-plots.R b/tests/testthat/test-plots.R index 611962a..73d764a 100644 --- a/tests/testthat/test-plots.R +++ b/tests/testthat/test-plots.R @@ -1,5 +1,5 @@ test_that("iscamboxplot works correctly with one variable", { - vdiffr::expect_doppelganger("iscamboxplot-one-var", function() { + vdiffr::expect_doppelganger("iscamboxplot-one-variable", function() { iscamboxplot( mtcars$mpg, main = "mtcars Cylinders iscamdotplot", @@ -9,7 +9,7 @@ test_that("iscamboxplot works correctly with one variable", { }) test_that("iscamboxplot works correctly with two variables", { - vdiffr::expect_doppelganger("iscamboxplot-two-vars", function() { + vdiffr::expect_doppelganger("iscamboxplot-two-variables", function() { iscamboxplot( mtcars$mpg, mtcars$am, @@ -21,7 +21,7 @@ test_that("iscamboxplot works correctly with two variables", { }) test_that("iscamdotplot works correctly with one variable", { - vdiffr::expect_doppelganger("iscamdotplot-one-var", function() { + vdiffr::expect_doppelganger("iscamdotplot-one-variable", function() { iscamdotplot( mtcars$cyl, main = "mtcars Cylinders iscamdotplot", @@ -31,7 +31,7 @@ test_that("iscamdotplot works correctly with one variable", { }) test_that("iscamdotplot works correctly with two variables", { - vdiffr::expect_doppelganger("iscamdotplot-two-vars", function() { + vdiffr::expect_doppelganger("iscamdotplot-two-variables", function() { iscamdotplot( mtcars$mpg, mtcars$am, diff --git a/tests/testthat/test-prop-tests.R b/tests/testthat/test-prop-tests.R new file mode 100644 index 0000000..414b1db --- /dev/null +++ b/tests/testthat/test-prop-tests.R @@ -0,0 +1,64 @@ +test_that("iscamonepropztest agrees with prop.test", { + res <- capture_plot_result(suppressWarnings(iscamonepropztest( + observed = 35, + n = 50, + hypothesized = 0.5, + alternative = "greater", + conf.level = 0.95 + ))) + + statistic <- 35 / 50 + z_expected <- (statistic - 0.5) / sqrt(0.5 * (1 - 0.5) / 50) + p_expected <- signif( + prop.test( + 35, + 50, + p = 0.5, + alternative = "greater", + correct = FALSE + )$p.value, + 4 + ) + critical <- qnorm((1 - 0.95) / 2) + se_stat <- sqrt(statistic * (1 - statistic) / 50) + lower <- statistic + critical * se_stat + upper <- statistic - critical * se_stat + + expect_equal(res$value$zvalue, z_expected, tolerance = 1e-6) + expect_equal(res$value$pvalue, p_expected, tolerance = 1e-6) + expect_equal(res$value$lower, lower, tolerance = 1e-6) + expect_equal(res$value$upper, upper, tolerance = 1e-6) + + expect_snapshot(res$output) +}) + +test_that("iscamtwopropztest matches two-sample z test calculations", { + res <- capture_plot_result(suppressWarnings(iscamtwopropztest( + observed1 = 35, + n1 = 50, + observed2 = 28, + n2 = 45, + hypothesized = 0, + alternative = "greater", + conf.level = 0.95 + ))) + + p1 <- 35 / 50 + p2 <- 28 / 45 + diff_est <- p1 - p2 + pooled <- (35 + 28) / (50 + 45) + z_expected <- (diff_est - 0) / sqrt(pooled * (1 - pooled) * (1 / 50 + 1 / 45)) + p_expected <- signif(1 - pnorm(z_expected), 4) + + se_diff <- sqrt(p1 * (1 - p1) / 50 + p2 * (1 - p2) / 45) + critical <- qnorm((1 - 0.95) / 2) + lower <- diff_est + critical * se_diff + upper <- diff_est - critical * se_diff + + expect_equal(res$value$zvalue, z_expected, tolerance = 1e-6) + expect_equal(res$value$pvalue, p_expected, tolerance = 1e-6) + expect_equal(res$value$lower, lower, tolerance = 1e-6) + expect_equal(res$value$upper, upper, tolerance = 1e-6) + + expect_snapshot(res$output) +}) diff --git a/tests/testthat/test-t-suite.R b/tests/testthat/test-t-suite.R new file mode 100644 index 0000000..94efc9f --- /dev/null +++ b/tests/testthat/test-t-suite.R @@ -0,0 +1,106 @@ +test_that("iscaminvt reports requested t quantiles", { + res_below <- capture_plot_result(iscaminvt( + 0.05, + df = 15, + direction = "below" + )) + res_outside <- capture_plot_result(iscaminvt( + 0.1, + df = 10, + direction = "outside" + )) + + expect_equal( + res_below$value$answer, + round(qt(0.05, 15, lower.tail = TRUE), 3), + tolerance = 1e-6 + ) + expect_equal( + res_outside$value$answer1, + round(qt(0.05, 10, lower.tail = TRUE), 3), + tolerance = 1e-6 + ) + expect_equal( + res_outside$value$answer2, + round(qt(0.95, 10, lower.tail = TRUE), 3), + tolerance = 1e-6 + ) +}) + +test_that("iscamtprob matches t tail probabilities", { + res_below <- capture_plot_result(iscamtprob( + xval = -2.05, + df = 10, + direction = "below" + )) + res_between <- capture_plot_result(iscamtprob( + xval = -2, + xval2 = 2, + df = 12, + direction = "between" + )) + + expect_null(res_below$value) + expect_null(res_between$value) + + expect_snapshot(res_below$output) + expect_snapshot(res_between$output) +}) + +test_that("iscamonesamplet returns Welch statistics", { + res <- capture_plot_result(suppressWarnings(iscamonesamplet( + xbar = 2.5, + sd = 1.2, + n = 30, + alternative = "greater", + hypothesized = 2, + conf.level = 0.95 + ))) + + se <- 1.2 / sqrt(30) + t_expected <- (2.5 - 2) / se + p_expected <- pt(t_expected, df = 29, lower.tail = FALSE) + critical <- qt((1 - 0.95) / 2, df = 29) + lower <- 2.5 + critical * se + upper <- 2.5 - critical * se + + expect_null(res$value) + + expect_snapshot(res$output) +}) + +test_that("iscamtwosamplet returns Welch two-sample results", { + x1 <- 5 + sd1 <- 2 + n1 <- 30 + x2 <- 4 + sd2 <- 1.5 + n2 <- 28 + conf <- 0.95 + + res <- capture_plot_result(suppressWarnings(iscamtwosamplet( + x1 = x1, + sd1 = sd1, + n1 = n1, + x2 = x2, + sd2 = sd2, + n2 = n2, + hypothesized = 0, + alternative = "two.sided", + conf.level = conf + ))) + + se <- sqrt(sd1^2 / n1 + sd2^2 / n2) + df_calc <- (sd1^2 / n1 + sd2^2 / n2)^2 / + ((sd1^2 / n1)^2 / (n1 - 1) + (sd2^2 / n2)^2 / (n2 - 1)) + df_expected <- signif(df_calc, 4) + t_expected <- (x1 - x2) / se + p_expected <- 2 * pt(-abs(t_expected), df_expected) + critical <- qt((1 - conf) / 2, df_expected) + lower <- (x1 - x2) + critical * se + upper <- (x1 - x2) - critical * se + + expect_null(res$value) + + expect_snapshot(res$output) +})