在 readR 中处理以行名作为第一个未命名列的“R 类型”文本文件

问题描述

读取带有基本 read.table 的文本文件时,

"如果没有指定 row.names 并且标题行比列数少一个条目,则第一列将被视为行名称。这允许从格式中读取数据帧在其中打印它们。如果指定了 row.names 并且不引用第一列,则该列将从此类文件中丢弃。"

但是我如何使用 tidyverse 的 readr 读取这样的文件

考虑这个文件(我们称之为 test.txt):

col1    col2
sample1 2   3
sample2 2   5

它是制表符分隔的,第一行有两个由制表符分隔的项目,第二行和第三行有三个项目由两个制表符分隔。

基础 R:

> read.table("test.txt")
        col1 col2
sample1    2    3
sample2    2    5

带有读取器的 R:

> read_delim("test.txt",delim="\t")

-- Column specification --------------------------------------------------------------------------------------------------
cols(
  col1 = col_character(),col2 = col_double()
)

Warning: 2 parsing failures.
row col  expected    actual                                     file
  1  -- 2 columns 3 columns 'C:\Users\moje4671\Desktop\test.txt'
  2  -- 2 columns 3 columns 'C:\Users\moje4671\Desktop\test.txt'

# A tibble: 2 x 2
  col1     col2
  <chr>   <dbl>
1 sample1     2
2 sample2     2

不幸的是,我确实有很多文件遵循这个约定(我不会讨论它的优点)。

我发现很难想象没有简单的 readr 方法来读取这种文件.. 毕竟,这是一种合法的 R 文件格式(可以这么说);

当然,解决方法

> as.tibble(read.table("test.txt"))
# A tibble: 2 x 2
   col1  col2
  <int> <int>
1     2     3
2     2     5

加上一些魔法来保留行名,好吧)

.. 但这有点违背了使用 readr 的目的(更快,没有自动类型转换等......)。有什么更好的方法吗?

解决方法

您需要更多地使用 read_delim 的函数参数的可能性才能使其工作:

read_delim("test.txt",delim = "\t",skip = 1,col_names = c("col1","col2"),col_types = "_ii")

给出:

# A tibble: 2 x 2
   col1  col2
  <int> <int>
1     2     3
2     2     5

如果您愿意看看 tidyverse,另一种选择是使用 -package 中的 fread-function:

fread("test.txt")

给出:

        V1 col1 col2
1: sample1    2    3
2: sample2    2    5

如您所见,行名现在位于第一列中。您可以使用 drop-argument:

消除这种情况
fread("test.txt",drop = 1)

给出:

   col1 col2
1:    2    3
2:    2    5