使用 readr 包中的 tidy-selection 指定跨多个列的列类型

2023-12-08

我尝试使用read_csv from {readr}读一个CSV文件到 R 中。为了演示我的真正问题,我重置了参数guess_max最初为 5(默认为 1000)

library(readr)
formals(read_csv)$guess_max <- 5

并以较小的文字数据为例:

csv <- I(
"ID, Col1, Col2, VarA, VarB, VarC
1, NA, NA, NA, NA, NA
2, NA, NA, NA, NA, NA
3, NA, NA, NA, NA, NA
4, NA, NA, NA, NA, NA
5, 0, 1, x, y, z
6, NA, NA, NA, NA, NA")

read_csv(csv)

# # A tibble: 6 × 6
#      ID  Col1    Col2    VarA   VarB   VarC 
#   <dbl>  <lgl>   <lgl>   <lgl>  <lgl>  <lgl>
# 1     1  NA      NA      NA     NA     NA   
# 2     2  NA      NA      NA     NA     NA   
# 3     3  NA      NA      NA     NA     NA   
# 4     4  NA      NA      NA     NA     NA   
# 5     5  FALSE*  TRUE*   NA*    NA*    NA*
# 6     6  NA      NA      NA     NA     NA

*: 出现解析问题


受影响guess_max,仅前 5 行(列名称和ID1 到 4) 用于猜测列类型。因为值在ID1 到 4 全部缺失,所有列都被猜测为logical并被错误地解析:

  • 0, 1(整数)→FALSE, TRUE(逻辑)
  • 'x', 'y', 'z'(人物)→NA(逻辑)

在这种情况下我必须设置col_types手动:

read_csv(csv, col_types = cols(Col1 = col_integer(), Col2 = col_integer(),
                               VarA = col_character(), VarB = col_character(), VarC = col_character()))

# # A tibble: 6 × 6                                                                                                   
#      ID  Col1  Col2 VarA  VarB  VarC 
#   <dbl> <int> <int> <chr> <chr> <chr>
# 1     1    NA    NA NA    NA    NA   
# 2     2    NA    NA NA    NA    NA   
# 3     3    NA    NA NA    NA    NA   
# 4     4    NA    NA NA    NA    NA   
# 5     5     0     1 x     y     z    
# 6     6    NA    NA NA    NA    NA

当列太多时,一一提供列类型很烦人。如果我想指定的那些列的名称有一些模式,我希望使用-like 语法来指定跨多个列的类型,例如across() in {dplyr}。伪代码如下:

read_csv(csv, col_types = cols(across(starts_with("Col"), col_integer()),
                               across(starts_with("Var"), col_character())))

是否可以通过readr本身还是其他附加包?

提前致谢!


Edits

我需要使用col_xxx()而不是它们的缩写('i', 'c'等)来创建更通用的列规范,例如

cols(across(contains("Date"), col_date(format = "%m-%d-%Y")),
     across(Fct1:Fct9, col_factor(levels = custom_levels)))

The read_delim()family 使用 tidy-selection 来选择带有参数的列col_select。您可以利用此参数将 tidy-selection 合并到列类型的规范中。下面是一个简单的实现。关键是设置n_max = 0L仅读取列名称行。

版本1

col_across <- function(.cols, .fns, file) {
  col_selected <- read_csv(file, n_max = 0L, col_select = {{.cols}}, show_col_types = FALSE)
  lapply(col_selected, function(x) .fns)
}
df <- read_csv(csv, col_types = c(col_across(starts_with("Col"), col_integer(), csv),
                                  col_across(VarA:VarC, col_factor(c('x', 'y', 'z')), csv)))

上面的方法很简单,但是对于一些人来说还可以缺点:

  1. 相同的文件源(即对象csv)需要传递给每个col_across().
  2. The read_delim系列包括多种变体,例如read_csv, read_csv2, read_tsv。打电话时df <- read_xxx(...),你必须确认col_across()已经使用了一致的read_xxx读取列名。

版本2

的改进版本col_across被开发来自动检测哪些read_xxx使用,并从外部调用中检索文件源。

col_across <- function(.cols, .fns) {
  sc <- sys.call(1L)
  sc <- match.call(match.fun(sc[[1L]]), sc)
  read_call <- sc[c(1L, match("file", names(sc), 0L))]
  read_call$n_max <- 0L
  read_call$col_select <- substitute(.cols)
  read_call$show_col_types <- FALSE
  lapply(eval(read_call, parent.frame()), function(x) .fns)
}
df <- read_csv(csv, col_types = c(col_across(starts_with("Col"), col_integer()),
                                  col_across(VarA:VarC, col_factor(c('x', 'y', 'z')))))

请注意,这个版本col_across只能在内部使用read_delim()家庭,作为across is to mutate in dplyr.


检查色谱柱规格

spec(df)

# cols(
#   ID = col_double(),
#   Col1 = col_integer(),
#   Col2 = col_integer(),
#   VarA = col_factor(levels = c("x", "y", "z"), ordered = FALSE, include_na = FALSE),
#   VarB = col_factor(levels = c("x", "y", "z"), ordered = FALSE, include_na = FALSE),
#   VarC = col_factor(levels = c("x", "y", "z"), ordered = FALSE, include_na = FALSE)
# )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 readr 包中的 tidy-selection 指定跨多个列的列类型 的相关文章

随机推荐

  • Laravel 4 - 无法检索一对多关系中的数据

    我有一个报价模型 class Quote extends Eloquent public function quote lines return this gt hasMany QuoteLine 还有一个 QuoteLine 模型 cla
  • 添加 Azure Ad Oauth2 JWT 令牌声明

    我只是想知道是否有办法通过 Azure 门户向 Azure Ad OAuth2 JWT 令牌添加或指定自定义声明 或者这是唯一可能的代码方面 据我所知 Azure AD目前不支持发出自定义声明 作为解决方法 我们可以使用 Azure AD
  • 通过名称获取 React 组件

    有没有办法通过名称访问 React 组件 例如 使用 React devtools 我可以搜索组件并使用以下命令访问控制台中最近选择的组件 r 有没有办法在没有 React 开发工具的情况下访问这些组件 IE 我可以使用查询来获取这些组件吗
  • 删除R中欧元符号后面的字符

    我有一个欧元符号保存在 欧元 变量中 euro lt u20AC euro 1 并且 eurosearch 变量包含 此 SOW 中定义的服务 价格为 15 896 80 欧元 如果从 执行 eurosearch 1 services as
  • 如何使用 iso_c_binding 声明指针的指针?

    我正在写一个iso c 绑定在 Fortran 中调用具有以下原型的 C 函数 int zmat run const size t inputsize unsigned char inputstr size t outputsize uns
  • 电源外壳。修改 ascii 文本文件字符串,其中行号字符串已打开。交换机和 .NET 框架或 cmdlet 和管道?哪个更快?

    如何使用易于阅读且易于使用 PowerShell 5 添加 修改 删除的搜索字符串来修改 Windows ascii 文本文件中的字符串 LINE2 行号 LINE2 is on 此脚本将解析 2500 行文件 找到 139 个字符串实例
  • 如何过滤 JSON 对象

    我有一个 JSON 对象 它是包含姓名 FName 城市 班级 联系人的学生列表 现在我只想过滤属于特定城市的对象 学生 我可以过滤邮件json对象吗 Students id 1 Name Student1 FName FName1 Cla
  • 我无法从 Hadoop 客户端连接到 Hadoop 服务器

    Hadoop 服务器位于 Kubernetes 中 Hadoop客户端位于外部网络 所以我尝试使用 kubernetes service 来使用 Hadoop 服务器 但hadoop fs put不适用于 Hadoop 客户端 据我所知 n
  • R ggplot2 - geom_smooth,具有来自第三个连续变量的渐变颜色

    有没有办法绘制平滑曲线 x var1 y var2 并相对于第三个连续变量 z var3 为其着色 我正在使用以下代码 library ggplot2 x runif 100 20 20 y 2 x x 2 rnorm 100 0 50 z
  • 多文件上传器仅发送一个文件

    我有一个多文件输入 我可以选择多个文件 但是当我在表单操作页面上 var dump 文件变量时 只有一个文件
  • 子查询返回超过 1 个值

    我需要在 SQL Server 2008 中设置一个作业 以便在每个月的第一天运行 向我们的客户发送电子邮件 但是 我不知道如何循环子查询的结果 导致出现此错误消息 子查询返回超过 1 个值 这是不允许的 当 子查询后面有 gt 或者当子查
  • Hibernate 批量大小混乱

    该程序一个接一个地执行数万次连续插入 我以前从未使用过 Hibernate 我的性能变得非常慢 如果我只是手动连接并执行 SQL 我的速度会快 10 12 倍 根据许多 hibernate 教程 我的 batch size 设置为 50 这
  • 上传到Heroku DB rake:迁移问题

    heroku 上传出现问题 对于 RoR 来说还很陌生 所以请原谅初学者的问题 我正在关注 Ruby on Rails 教程 http ruby railstutorial org 在搭建脚手架之后 我输入 heroku rake db m
  • JavaFX 的 TextField 的值更改侦听器

    我想添加一种listener to my JavaFX s TextField当用户改变值时TextField 应用程序在控制台上打印一些内容 我进行了搜索 发现以下非常相似的问题 JTextField 的值更改侦听器 提到的问题的答案非常
  • 带有 $.ajax 类型的自定义标头 jnop 或 json

    我在使用 jQuery ajax JSON 或 JSONP 请求发送一些自定义标头时遇到问题 代码如下所示 ajax beforeSend function xhr xhr setRequestHeader X VER VER xhr se
  • 迭代并打印常规闭包的内容

    在一个循环中 我创建了 4 个闭包并将它们添加到列表中 closureList for int i 0 i lt 4 i def cl def A i closureList add cl closureList each print it
  • 查找数组中的特殊数字

    数组中有很多数字 除了一个特殊数字出现一次外 每个数字都出现3次 那么问题来了 如何找到数组中的特殊数字呢 现在我只能提出一些基数排序和快速排序的方法 无法利用问题的性质 所以我需要一些其他的算法 感谢您的帮助 将数字按位 mod 3 添加
  • 如何向 VBA ListBox 添加水平滚动条

    我想向 VBA ListBox 添加水平滚动条 看来内置的ListBox不会自动添加水平滚动条 我有许多字段 其内容超出了列表框的宽度 因此用户无法读取 I found 本文 但是由于访问 ListBox 的 hwnd 这在 VBA 中显然
  • 如何在for循环中每次更新标签

    我正在开发一个 WinForm 项目 其中有一个标签for环形 我想每次执行后显示标签label text陈述 但它并不是每次都显示 而是在 for 循环完成后显示 我试图通过使用来实现这一点Thread Sleep 但我不能 请帮我 注意
  • 使用 readr 包中的 tidy-selection 指定跨多个列的列类型

    我尝试使用read csv from readr 读一个CSV文件到 R 中 为了演示我的真正问题 我重置了参数guess max最初为 5 默认为 1000 library readr formals read csv guess max