R:读入一行子集并将其转换为传统格式(首选data.table方法)

问题描述 投票:2回答:1

我有一个文件,它有超过一亿行,并分散在整个字段中有额外的制表符分隔符。我需要将有问题的行读入R而忽略其他行,因为涉及的文件很大。

某些行中带有额外分隔符的示例txt文件:

text_file <-"My\tname\tis\tAlpha\nMy\tname\tis\t\t\tBravo\nMy\tname\tis\tCharlie\nMy\tname\tis\t\t\tDelta\nMy\tname\tis\tEcho"

我尝试的第一件事是使用'readLines'函数,但是我可以指定要停止的行仍然会读到其他所有内容,但仍然可能过多

readLines(textConnection(text_file), n = 4)

[1] "My\tname\tis\tAlpha"     "My\tname\tis\t\t\tBravo" "My\tname\tis\tCharlie"   "My\tname\tis\t\t\tDelta"

然后我意识到如果我将分隔符指定为可能永远不会出现的内容,我还可以使用其他数据集导入函数。 data.table包中的“fread”函数对于它来说是完美的,因为它是处理像我这样的大型数据集的最快方式,但是当我尝试它时,数据的格式是我无法真正进一步处理的:

library(data.table)
library(stringi)

lines <- fread(text_file, sep = NULL, header = FALSE, skip = 1, nrows = 3)

> lines
                        V1
1: My\tname\tis\t\t\tBravo
2:   My\tname\tis\tCharlie
3: My\tname\tis\t\t\tDelta

> invalid_delimiter_rows <- which(stri_count_regex(lines, "\\t") != 3)
Warning message:
In stri_count_regex(lines, "\\t") :
  argument is not an atomic vector; coercing

我最好不要在导入后转换这些数据,但是当我尝试将其更改为字符向量或列表时,它仍然是一个错误的格式(连接被认为是字符串的一部分而不是函数)。我能解决这个问题的计算时间最有效的方法是什么?

> class(lines)

[1] "data.table" "data.frame"

> as.character(lines)

[1] "c(\"My\\tname\\tis\\t\\t\\tBravo\", \"My\\tname\\tis\\tCharlie\", \"My\\tname\\tis\\t\\t\\tDelta\")"
r types import data.table delimiter
1个回答
1
投票

让我们复制这个过程直到fread()导入:

# your example string
text_file <-"My\tname\tis\tAlpha\nMy\tname\tis\t\t\tBravo\nMy\tname\tis\tCharlie\nMy\tname\tis\t\t\tDelta\nMy\tname\tis\tEcho"

# import
library(data.table)
lines <- fread(text_file, sep = NULL, header = FALSE, skip = 1, nrows = 5)
lines
                        V1
1: My\tname\tis\t\t\tBravo
2:   My\tname\tis\tCharlie
3: My\tname\tis\t\t\tDelta
4:      My\tname\tis\tEcho

当你尝试

as.character(lines)
[1] "c(\"My\\tname\\tis\\t\\t\\tBravo\", \"My\\tname\\tis\\tCharlie\", \"My\\tname\\tis\\t\\t\\tDelta\", \"My\\tname\\tis\\tEcho\")"

它转换所有data.table的字符,因此每列将是一个连接的向量。见下文:

as.character(data.table(lines$V1, lines$V1))
[1] "c(\"My\\tname\\tis\\t\\t\\tBravo\", \"My\\tname\\tis\\tCharlie\", \"My\\tname\\tis\\t\\t\\tDelta\", \"My\\tname\\tis\\tEcho\")"
[2] "c(\"My\\tname\\tis\\t\\t\\tBravo\", \"My\\tname\\tis\\tCharlie\", \"My\\tname\\tis\\t\\t\\tDelta\", \"My\\tname\\tis\\tEcho\")"

你想要的只是提取lines$V1,它已经是一个字符向量。

lines$V1
[1] "My\tname\tis\t\t\tBravo" "My\tname\tis\tCharlie"   "My\tname\tis\t\t\tDelta" "My\tname\tis\tEcho"     
© www.soinside.com 2019 - 2024. All rights reserved.