R:读取行的子集并将其转换为常规格式(首选 data.table 方法)
R: Read in a subset of lines and turn it into a conventional format (data.table approach preferred)
我有一个超过一亿行的文件,并且分散在各处,字段中有额外的制表符分隔符。由于涉及的文件很大,我需要将有问题的行读入 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\")"
让我们重复该过程,直到 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"
我有一个超过一亿行的文件,并且分散在各处,字段中有额外的制表符分隔符。由于涉及的文件很大,我需要将有问题的行读入 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\")"
让我们重复该过程,直到 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"