You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在readr中用tidy选择语法批量指定多列类型?

解决方案:批量指定列类型(支持tidy-select语法)

readr本身并未内置类似dplyr::across()的语法直接在cols()中使用,但可以通过两种方式实现你的需求:

一、使用vroom包(tidyverse官方替代,原生支持)

{vroom}是readr的高性能替代包,它的vroom()函数允许在col_types参数中直接使用tidy-select选择器,完美匹配你想要的写法:

library(vroom)

# 自定义因子级别
custom_levels <- c("low", "medium", "high")

# 读取文件,批量指定列类型
vroom("your_file.csv",
  col_types = list(
    starts_with("Col") = col_integer(),
    starts_with("Var") = col_character(),
    contains("Date") = col_date(format = "%m-%d-%Y"),
    Fct1:Fct9 = col_factor(levels = custom_levels)
  ),
  guess_max = 5
)

这种方式无需额外封装,直接支持你需要的所有场景:按列名前缀、关键词匹配、列范围指定,且可以使用完整的col_xxx()函数(带参数)。

二、基于readr+tidyselect+purrr手动实现

如果必须使用readr,可以通过tidyselect筛选列名,结合purrr生成列类型规范:

步骤1:先获取文件的列名(不解析数据)

library(readr)
library(tidyselect)
library(purrr)

# 读取列名
col_names <- read_csv("your_file.csv", n_max = 0) %>% names()

步骤2:生成列类型规范

custom_levels <- c("low", "medium", "high")

col_spec <- cols(
  # 批量指定前缀为Col的列为整数
  !!!set_names(
    map(starts_with("Col", vars = col_names), ~col_integer()),
    starts_with("Col", vars = col_names)
  ),
  # 批量指定前缀为Var的列为字符
  !!!set_names(
    map(starts_with("Var", vars = col_names), ~col_character()),
    starts_with("Var", vars = col_names)
  ),
  # 批量指定包含Date的列为日期(自定义格式)
  !!!set_names(
    map(contains("Date", vars = col_names), ~col_date(format = "%m-%d-%Y")),
    contains("Date", vars = col_names)
  ),
  # 批量指定Fct1到Fct9为因子(自定义级别)
  !!!set_names(
    map(all_of(paste0("Fct", 1:9)), ~col_factor(levels = custom_levels)),
    paste0("Fct", 1:9)
  )
)

步骤3:读取文件

read_csv("your_file.csv", col_types = col_spec, guess_max = 5)

可选:封装成复用函数

如果需要多次使用,可以封装一个函数简化操作:

make_readr_col_spec <- function(col_names, ...) {
  args <- rlang::enquos(...)
  spec_list <- list()
  
  for (arg in args) {
    selector <- rlang::f_lhs(arg)
    col_fun <- rlang::f_rhs(arg)
    selected_cols <- eval_select(selector, tibble::tibble(!!!set_names(col_names, col_names)))
    spec_list[names(selected_cols)] <- map(names(selected_cols), ~rlang::eval_tidy(col_fun))
  }
  
  do.call(cols, spec_list)
}

# 使用示例
col_spec <- make_readr_col_spec(col_names,
  starts_with("Col") ~ col_integer(),
  starts_with("Var") ~ col_character(),
  contains("Date") ~ col_date(format = "%m-%d-%Y"),
  Fct1:Fct9 ~ col_factor(levels = custom_levels)
)

内容的提问来源于stack exchange,提问作者user18894435

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:23:13