Skip to content

Commit 7067e91

Browse files
committed
Support tidyselect expressions in cis_read columns
1 parent fd4ce1f commit 7067e91

6 files changed

Lines changed: 70 additions & 12 deletions

File tree

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Imports:
2424
jsonlite,
2525
rappdirs,
2626
rlang,
27-
tibble
27+
tibble,
28+
tidyselect
2829
Suggests:
2930
devtools,
3031
pkgdown,

R/read.R

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ cis_open <- function() {
2828
#' @param fecha_min Minimum survey date, included. `NULL` means no lower bound.
2929
#' @param fecha_max Maximum survey date, included. `NULL` means no upper bound.
3030
#' @param estudios Optional vector of study codes.
31-
#' @param cols Optional character vector of columns to select.
31+
#' @param cols Optional tidyselect expression or character vector of columns to
32+
#' select.
3233
#' @param keep_core_cols If `TRUE`, always include `estudio`, `fecha`, `genero`,
3334
#' and `edad` when `cols` is supplied.
3435
#' @param collect If `TRUE`, return a tibble in memory. If `FALSE`, return a lazy
@@ -47,6 +48,8 @@ cis_open <- function() {
4748
#' cols = c("estudio", "fecha", "genero", "edad", "idv", "recuerdo")
4849
#' )
4950
#'
51+
#' cis_read(cols = dplyr::starts_with("val_"))
52+
#'
5053
#' cis_read(fecha_min = "2020-01-01", collect = FALSE) |>
5154
#' dplyr::count(estudio) |>
5255
#' dplyr::collect()
@@ -57,6 +60,7 @@ cis_read <- function(fecha_min = NULL,
5760
cols = NULL,
5861
keep_core_cols = TRUE,
5962
collect = TRUE) {
63+
cols <- rlang::enquo(cols)
6064
cis_check_bool(keep_core_cols, "keep_core_cols")
6165
cis_check_bool(collect, "collect")
6266

@@ -66,10 +70,6 @@ cis_read <- function(fecha_min = NULL,
6670
cli::cli_abort("{.arg fecha_min} cannot be later than {.arg fecha_max}.")
6771
}
6872

69-
if (!is.null(cols) && (!is.character(cols) || anyNA(cols))) {
70-
cli::cli_abort("{.arg cols} must be a character vector of column names.")
71-
}
72-
7373
ds <- cis_open()
7474
available_cols <- names(ds)
7575
selected_cols <- cis_selected_cols(cols, keep_core_cols, available_cols)
@@ -97,10 +97,10 @@ cis_read <- function(fecha_min = NULL,
9797
}
9898

9999
cis_selected_cols <- function(cols, keep_core_cols, available_cols) {
100-
if (is.null(cols)) {
100+
if (rlang::quo_is_missing(cols) || identical(rlang::quo_get_expr(cols), NULL)) {
101101
return(NULL)
102102
}
103-
selected <- unique(cols)
103+
selected <- cis_eval_cols(cols, available_cols)
104104
if (keep_core_cols) {
105105
selected <- unique(c(.cis_core_cols, selected))
106106
}
@@ -115,6 +115,36 @@ cis_selected_cols <- function(cols, keep_core_cols, available_cols) {
115115
selected
116116
}
117117

118+
cis_eval_cols <- function(cols, available_cols) {
119+
expr <- rlang::quo_get_expr(cols)
120+
value <- NULL
121+
if (is.character(expr) || rlang::is_symbol(expr)) {
122+
value <- tryCatch(
123+
rlang::eval_tidy(cols),
124+
error = function(e) NULL
125+
)
126+
}
127+
if (is.character(value)) {
128+
if (anyNA(value)) {
129+
cli::cli_abort("{.arg cols} must not contain missing values.")
130+
}
131+
return(unique(value))
132+
}
133+
134+
data <- stats::setNames(rep(list(logical()), length(available_cols)), available_cols)
135+
selected <- tryCatch(
136+
tidyselect::eval_select(cols, data = data, allow_rename = FALSE),
137+
error = function(e) {
138+
cli::cli_abort(c(
139+
"Could not evaluate {.arg cols} as a tidyselect expression.",
140+
"x" = conditionMessage(e),
141+
"i" = "Use column names, helpers such as {.code dplyr::starts_with()}, or {.code dplyr::all_of()}."
142+
))
143+
}
144+
)
145+
names(selected)
146+
}
147+
118148
#' List available CIS columns
119149
#'
120150
#' @return A character vector with column names.

man/cis_read.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/cislongitudinal-package.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/helper.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ create_test_parquet <- function(path = file.path(local_test_cache(), "cis-longit
1515
genero = c("Mujer", "Hombre", "Mujer"),
1616
edad = c(35L, 47L, 52L),
1717
idv = c("PSOE", "PP", "SUMAR"),
18-
recuerdo = c("PSOE", "PP", "UP")
18+
recuerdo = c("PSOE", "PP", "UP"),
19+
val_min_1 = c(4.5, 5.2, 6.1),
20+
val_min_2 = c(3.8, 4.1, 5.0)
1921
)
2022
arrow::write_parquet(df, path)
2123
path

tests/testthat/test-read.R

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ test_that("cis_read includes core columns when requested", {
77
expect_named(df, c("estudio", "fecha", "genero", "edad", "idv"))
88
})
99

10+
test_that("cis_read accepts tidyselect helpers", {
11+
dir <- local_test_cache()
12+
create_test_parquet(file.path(dir, "cis-longitudinal.parquet"))
13+
14+
df <- cis_read(
15+
fecha_min = "2023-01-01",
16+
cols = c(dplyr::starts_with("val_min"))
17+
)
18+
19+
expect_named(df, c("estudio", "fecha", "genero", "edad", "val_min_1", "val_min_2"))
20+
})
21+
22+
test_that("cis_read accepts character vectors through all_of", {
23+
dir <- local_test_cache()
24+
create_test_parquet(file.path(dir, "cis-longitudinal.parquet"))
25+
cols <- c("idv", "recuerdo")
26+
27+
df <- cis_read(cols = dplyr::all_of(cols), keep_core_cols = FALSE)
28+
29+
expect_named(df, cols)
30+
})
31+
1032
test_that("cis_read fails with missing columns", {
1133
dir <- local_test_cache()
1234
create_test_parquet(file.path(dir, "cis-longitudinal.parquet"))
@@ -60,6 +82,6 @@ test_that("cis_info reports row counts and manifest dates when available", {
6082

6183
info <- cis_info()
6284
expect_equal(info$rows, 3)
63-
expect_equal(info$columns, 6)
85+
expect_equal(info$columns, 8)
6486
expect_equal(info$manifest_updated_at, "2026-06-30T10:27:15+0200")
6587
})

0 commit comments

Comments
 (0)