Skip to content

Commit c259afa

Browse files
Merge branch 'master' into fix/134/legendborder
2 parents 7ea83e9 + 9d6a95b commit c259afa

11 files changed

Lines changed: 116 additions & 8 deletions

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# bayesplot (development version)
22

33
* Fixed legend border artifact in `ppc_freqpoly()` and `ppc_freqpoly_grouped()`.
4+
* Fixed `validate_chain_list()` colnames check to compare all chains, not just the first two.
5+
* Added test verifying `legend_move("none")` behaves equivalently to `legend_none()`.
6+
* Added singleton-dimension edge-case tests for exported `_data()` functions.
47
* Validate empty list and zero-row matrix inputs in `nuts_params.list()`.
58
* Validate user-provided `pit` values in `ppc_loo_pit_data()` and `ppc_loo_pit_qq()`, rejecting non-numeric inputs, missing values, and values outside `[0, 1]`.
69
* New `show_marginal` argument to `ppd_*()` functions to show the PPD - the marginal predictive distribution by @mattansb (#425)

R/helpers-mcmc.R

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,8 @@ validate_chain_list <- function(x) {
277277
abort("Each chain should have the same number of iterations.")
278278
}
279279

280-
cnames <- sapply(x, colnames)
281-
if (is.array(cnames)) {
282-
same_params <- identical(cnames[, 1], cnames[, 2])
283-
} else {
284-
same_params <- length(unique(cnames)) == 1
285-
}
280+
cnames <- lapply(x, colnames)
281+
same_params <- all(vapply(cnames[-1], identical, logical(1), cnames[[1]]))
286282
if (!same_params) {
287283
abort(paste(
288284
"The parameters for each chain should be in the same order",

tests/testthat/test-convenience-functions.R

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ test_that("legend_text returns correct theme object", {
120120
theme(legend.text = element_text(color = "purple", size = 16))
121121
)
122122
})
123+
test_that("legend_move('none') behaves like legend_none", {
124+
expect_equal(
125+
legend_move("none")$legend.position,
126+
legend_none()$legend.position,
127+
ignore_attr = TRUE
128+
)
129+
})
123130

124131
# axis and facet text --------------------------------------------------
125132
test_that("xaxis_text returns correct theme object", {
@@ -186,8 +193,6 @@ test_that("overlay_function returns the correct object", {
186193
a$constructor <- b$constructor <- NULL
187194
expect_equal(a, b, ignore_function_env = TRUE)
188195
})
189-
190-
191196
# tagged functions -------------------------------------------------------
192197

193198
test_that("as_tagged_function handles bare function (symbol)", {

tests/testthat/test-helpers-mcmc.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ test_that("validate_chain_list works", {
178178
"Each chain should have the same number of iterations")
179179
})
180180

181+
test_that("validate_chain_list detects colnames mismatch in chain 3+", {
182+
ch <- matrix(rnorm(20), nrow = 2, dimnames = list(NULL, c("a", "b", "c", "d", "e",
183+
"f", "g", "h", "i", "j")))
184+
chain3_bad <- ch
185+
colnames(chain3_bad)[1] <- "z"
186+
chains_ok <- list(ch, ch, ch)
187+
chains_bad <- list(ch, ch, chain3_bad)
188+
189+
expect_identical(validate_chain_list(chains_ok), chains_ok)
190+
expect_error(validate_chain_list(chains_bad), "parameters for each chain")
191+
})
192+
181193
test_that("chain_list2array works", {
182194
expect_mcmc_array(chain_list2array(chainlist))
183195
expect_mcmc_array(chain_list2array(chainlist1))

tests/testthat/test-ppc-discrete.R

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,27 @@ test_that("ppc_bars_data includes all levels", {
7777
expect_equal(d3$h[2], 0, ignore_attr = TRUE)
7878
})
7979

80+
test_that("ppc_bars_data handles single observation and single draw", {
81+
y1 <- 2L
82+
yrep1 <- matrix(c(1L, 2L, 3L, 2L, 2L), ncol = 1)
83+
d <- ppc_bars_data(y1, yrep1)
84+
expect_s3_class(d, "data.frame")
85+
expect_equal(d$y_obs[d$x == 2], 1)
86+
87+
# single draw: interval collapses to a point
88+
y_s <- c(1L, 2L, 3L, 2L)
89+
yrep_s <- matrix(c(1L, 2L, 2L, 3L), nrow = 1)
90+
d2 <- ppc_bars_data(y_s, yrep_s)
91+
expect_equal(d2$l, d2$m, ignore_attr = TRUE)
92+
expect_equal(d2$m, d2$h, ignore_attr = TRUE)
93+
})
94+
95+
test_that("ppc_bars_data prob = 0 collapses interval to median", {
96+
d <- ppc_bars_data(y_ord, yrep_ord, prob = 0)
97+
expect_equal(d$l, d$m, ignore_attr = TRUE)
98+
expect_equal(d$m, d$h, ignore_attr = TRUE)
99+
})
100+
80101

81102
# rootograms -----------------------------------------------------------
82103
yrep3 <- matrix(yrep2, nrow = 5, ncol = ncol(yrep2), byrow = TRUE)

tests/testthat/test-ppc-distributions.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ test_that("ppd_data handles a single replicate matrix", {
237237
expect_equal(d$value, c(11, 21))
238238
})
239239

240+
test_that("ppd_data handles single observation (single column)", {
241+
ypred <- matrix(c(1, 2, 3), ncol = 1)
242+
d <- ppd_data(ypred)
243+
expect_equal(nrow(d), 3)
244+
expect_true(all(d$y_id == 1))
245+
expect_equal(d$value, c(1, 2, 3))
246+
})
247+
240248

241249
# Visual tests -----------------------------------------------------------------
242250

tests/testthat/test-ppc-errors.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ test_that("ppc_error_data with group returns exact structure", {
8585
expect_equal(d$group[d$rep_id == 1], group)
8686
})
8787

88+
test_that("ppc_error_data handles single observation", {
89+
y1 <- 5
90+
yrep1 <- matrix(c(4, 6, 5), ncol = 1)
91+
d <- ppc_error_data(y1, yrep1)
92+
expect_equal(nrow(d), 3)
93+
expect_equal(d$value, y1 - yrep1[, 1])
94+
expect_true(all(d$y_obs == 5))
95+
})
96+
8897

8998
# Visual tests -----------------------------------------------------------------
9099

tests/testthat/test-ppc-intervals.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ test_that("ppd_intervals_data + y_obs column same as ppc_intervals_data", {
7272
expect_equal(tibble::add_column(d_group2, y_obs = d_group$y_obs, .after = "y_id"), d_group)
7373
})
7474

75+
test_that("ppd_intervals_data handles single observation and single draw", {
76+
yrep_1obs <- matrix(rnorm(25), ncol = 1)
77+
d <- ppd_intervals_data(yrep_1obs)
78+
expect_equal(nrow(d), 1)
79+
expect_true(d$ll <= d$l && d$l <= d$m && d$m <= d$h && d$h <= d$hh)
80+
81+
# single draw: all quantiles collapse to the value
82+
yrep_1draw <- matrix(rnorm(10), nrow = 1)
83+
d2 <- ppd_intervals_data(yrep_1draw)
84+
expect_equal(d2$ll, d2$m)
85+
expect_equal(d2$hh, d2$m)
86+
})
87+
7588
test_that("ppc_intervals_data does math correctly", {
7689
d <- ppc_intervals_data(y, yrep, prob = .4, prob_outer = .8)
7790
qs <- unname(quantile(yrep[, 1], c(.1, .3, .5, .7, .9)))

tests/testthat/test-ppc-loo.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,10 @@ test_that("ppc_loo_pit_data returns the expected structure for both boundary mod
432432
expect_equal(nrow(yrep_rows), grid_len * n_samples)
433433
expect_false(anyNA(d_bc$x))
434434
})
435+
436+
test_that("ppc_loo_pit_data works with a single pit value", {
437+
d <- suppressMessages(ppc_loo_pit_data(pit = 0.5, boundary_correction = FALSE, samples = 3))
438+
y_rows <- d[d$is_y, ]
439+
expect_equal(nrow(y_rows), 1)
440+
expect_equal(y_rows$value, 0.5)
441+
})

tests/testthat/test-ppc-scatterplots.R

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,29 @@ test_that("ppc_scatter_avg_data can take a custom fun_avg", {
3434
expect_equal(sums$value, colSums(yrep))
3535
})
3636

37+
test_that("ppc_scatter_data handles single observation and single draw", {
38+
y1 <- 5
39+
yrep1 <- matrix(c(4, 6, 5), ncol = 1)
40+
d <- ppc_scatter_data(y1, yrep1)
41+
expect_equal(nrow(d), 3)
42+
expect_true(all(d$y_obs == 5))
43+
expect_equal(d$value, c(4, 6, 5))
44+
45+
# single draw
46+
d2 <- ppc_scatter_data(y, yrep[1, , drop = FALSE])
47+
expect_equal(nrow(d2), length(y))
48+
expect_equal(d2$value, yrep[1, ])
49+
expect_equal(d2$y_obs, y)
50+
})
51+
52+
test_that("ppc_scatter_avg_data handles single observation", {
53+
y1 <- 5
54+
yrep1 <- matrix(c(4, 6, 5), ncol = 1)
55+
d <- ppc_scatter_avg_data(y1, yrep1)
56+
expect_equal(nrow(d), 1)
57+
expect_equal(d$value, mean(c(4, 6, 5)))
58+
expect_equal(d$y_obs, 5)
59+
})
3760

3861

3962
# Visual tests ------------------------------------------------------------

0 commit comments

Comments
 (0)