I use the following approach
library(readr)
fct_cols <- c("success", "attempts")
yr_cols <- c("birthyr", "firstyr")
mdy_cols <- c("birthdy")
chr_cols <- c("name")
create_spec <- function(col_format, names) {
col_spec <- rep_len(list(col_format), length.out = length(names))
setNames(col_spec, names)
}
col_spec_list <- c(
create_spec(col_character(), names = chr_cols),
create_spec(col_factor(), names = fct_cols),
create_spec(col_date(format = "%Y"), names = yr_cols),
create_spec(col_date(format = "%m/%d/%Y"), names = mdy_cols)
)
col_spec <- do.call(cols_only, col_spec_list)
col_spec
#> cols_only(
#> name = col_character(),
#> success = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
#> attempts = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
#> birthyr = col_date(format = "%Y"),
#> firstyr = col_date(format = "%Y"),
#> birthdy = col_date(format = "%m/%d/%Y")
#> )
# or the tidyverse alternative to `do.call()`
rlang::exec(cols_only, !!!col_spec_list)
#> cols_only(
#> name = col_character(),
#> success = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
#> attempts = col_factor(levels = NULL, ordered = FALSE, include_na = FALSE),
#> birthyr = col_date(format = "%Y"),
#> firstyr = col_date(format = "%Y"),
#> birthdy = col_date(format = "%m/%d/%Y")
#> )
Created on 2020-10-26 by the reprex package (v0.3.0)
I think one gets a good overview when defining all the columns that are of the same type in one place and it is less repetitive.