Skip to content

Commit 0785b7e

Browse files
committed
add optional vars argument to param_range() and param_glue()
this matches tidyselect
1 parent 0aa6b23 commit 0785b7e

File tree

3 files changed

+76
-33
lines changed

3 files changed

+76
-33
lines changed

R/tidy-params.R

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@
1111
#' When using `pars` for tidy parameter selection, the `regex_pars` argument
1212
#' is ignored because **bayesplot** supports using
1313
#' [tidyselect helper functions][tidyselect::select_helpers]
14-
#' (`starts_with()`, `contains()`, etc.) for the same purpose.
15-
#'
16-
#' **bayesplot** also exports additional helper functions
17-
#' `param_range()` and `param_glue()`
18-
#' to help with parameter selection. See the **Examples** section.
14+
#' (`starts_with()`, `contains()`, `num_range()`, etc.) for the same purpose.
15+
#' **bayesplot** also exports some additional helper functions
16+
#' to help with parameter selection:
17+
#' * `param_range()`: like [tidyselect::num_range()] but used when parameter
18+
#' indexes are in brackets (e.g. `beta[2]`).
19+
#' * `param_glue()`: for more complicated parameter names with multiple
20+
#' indexes (including variable names) inside the brackets
21+
#' (e.g., `beta[(Intercept) age_group:3]`).
22+
#' These functions can be used inside of `vars()`, `dplyr::select()`,
23+
#' and similar functions just like the
24+
#' [tidyselect helper functions][tidyselect::select_helpers].
25+
#' See the **Examples** section.
1926
#'
2027
#' @examples
2128
#' x <- example_mcmc_draws(params = 6)
@@ -28,9 +35,9 @@
2835
#' mcmc_hist(x, pars = vars(param_range("beta", c(1, 3, 4))))
2936
#'
3037
#' \donttest{
31-
#' ############################
32-
#' ## Example using rstanarm ##
33-
#' ############################
38+
#' #############################
39+
#' ## Examples using rstanarm ##
40+
#' #############################
3441
#' if (requireNamespace("rstanarm", quietly = TRUE)) {
3542
#' # see ?rstanarm::example_model
3643
#' fit <- example("example_model", package = "rstanarm", local=TRUE)$value
@@ -42,7 +49,7 @@
4249
#' mcmc_hist(posterior, pars = vars(size, contains("period")))
4350
#'
4451
#' # same as previous but using dplyr::select() and piping
45-
#' library(dplyr)
52+
#' library("dplyr")
4653
#' posterior %>%
4754
#' select(size, contains("period")) %>%
4855
#' mcmc_hist()
@@ -81,19 +88,27 @@ dplyr::vars
8188

8289
#' @rdname tidy-params
8390
#' @export
91+
#' @param vars `NULL` or a character vector of parameter names to choose from.
92+
#' This is only needed for the atypical use case of calling the function as a
93+
#' standalone function outside of `vars()`, `select()`, etc. Typically this is
94+
#' left as `NULL` and will be set automatically for the user.
8495
#' @param prefix,range For `param_range()` only, `prefix` is a string naming a
85-
#' parameter and `range` is an integer vector providing the indices of the
96+
#' parameter and `range` is an integer vector providing the indices of a
8697
#' subset of elements to select. For example, using
8798
#'
8899
#' param_range("beta", c(1,2,8))
89100
#'
90101
#' would select parameters named `beta[1]`, `beta[2]`, and `beta[8]`.
91102
#' `param_range()` is only designed for the case that the indices are integers
92-
#' surrounded by brackets.
103+
#' surrounded by brackets. If there are no brackets use
104+
#' [num_range()][tidyselect::select_helpers].
93105
#'
94-
param_range <- function(prefix, range) {
106+
param_range <- function(prefix, range, vars = NULL) {
107+
if (!is.null(vars) && !is.character(vars)) {
108+
abort("'vars' must be NULL or a character vector.")
109+
}
95110
nms <- paste0(prefix, "[", range, "]")
96-
param_matches <- match(nms, tidyselect::peek_vars())
111+
param_matches <- match(nms, vars %||% tidyselect::peek_vars())
97112
param_matches[!is.na(param_matches)]
98113
}
99114

@@ -113,7 +128,11 @@ param_range <- function(prefix, range) {
113128
#' See the **Examples** section below for demonstrations.
114129
#'
115130
#' @examples
116-
#' # more examples of param_glue()
131+
#' \dontrun{
132+
#' ###################################
133+
#' ## More examples of param_glue() ##
134+
#' ###################################
135+
#' library(dplyr)
117136
#' posterior <-
118137
#' structure(list(
119138
#' b_Intercept = rnorm(1000),
@@ -130,6 +149,7 @@ param_range <- function(prefix, range) {
130149
#' )
131150
#' str(posterior)
132151
#'
152+
#' # using one expression in braces
133153
#' posterior %>%
134154
#' select(
135155
#' param_glue(
@@ -138,6 +158,7 @@ param_range <- function(prefix, range) {
138158
#' ) %>%
139159
#' mcmc_hist()
140160
#'
161+
#' # using multiple expressions in braces
141162
#' posterior %>%
142163
#' select(
143164
#' param_glue(
@@ -146,13 +167,15 @@ param_range <- function(prefix, range) {
146167
#' type = c("Intercept", "Slope"))
147168
#' ) %>%
148169
#' mcmc_hist()
170+
#'}
149171
#'
150-
#'
151-
#'
152-
param_glue <- function(pattern, ...) {
172+
param_glue <- function(pattern, ..., vars = NULL) {
173+
if (!is.null(vars) && !is.character(vars)) {
174+
abort("'vars' must be NULL or a character vector.")
175+
}
153176
dots <- as.list(expand.grid(...))
154177
nms <- as.character(glue::glue_data(dots, pattern))
155-
param_matches <- match(nms, tidyselect::peek_vars())
178+
param_matches <- match(nms, vars %||% tidyselect::peek_vars())
156179
param_matches[!is.na(param_matches)]
157180
}
158181

man/tidy-params.Rd

Lines changed: 29 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-helpers-mcmc.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,14 @@ test_that("prepare_mcmc_array tidy parameter selection is same as traditional se
280280
prepare_mcmc_array(mat, pars = pars_char_2))
281281
})
282282

283-
test_that("tidy parameter selection errors if no matches", {
283+
test_that("tidy parameter selection throws correct errors", {
284284
expect_error(mcmc_hist(mat, pars = vars(contains("nonsense"))),
285285
"No parameters were found matching those names")
286+
287+
expect_error(param_range("alpha", 1:3, vars = list("a", "b", "c")),
288+
"'vars' must be NULL or a character vector.")
289+
expect_error(param_glue("alpha[{lev}]", lev = 1:3, vars = 1:3,
290+
"'vars' must be NULL or a character vector."))
286291
})
287292

288293
# rhat and neff helpers ---------------------------------------------------

0 commit comments

Comments
 (0)