问题描述
读取带有基本 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,另一种选择是使用 data.table-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