@@ -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
9999cis_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.
0 commit comments