在 data.table::fread 中绕过 "ghost" 换行符或文件结尾 (EOF)
Bypassing "ghost" line break or end of file (EOF) in data.table::fread
我正在使用 data.table::fread
将从(我可以访问的)数据库中导出的几个大型制表符分隔文本文件加载到 R 中。 fread
可以轻松快速地处理大部分文件,但其中一个文件生成定期报告的 fread
错误:
Error in fread(read_problem, encoding = "UTF-8", na.strings = "", header = TRUE, :
Expected sep (' ') but new line or EOF ends field ...
包含违规行的文件的较小版本(2000 行)可在此处获得 (RDS file)。
到目前为止,我是这样尝试诊断问题的:
library(data.table) # I'm using 1.9.7 development (same error with 1.9.6)
read_problem <- readRDS("read_problem.rds")
error <- fread(read_problem, encoding = "UTF-8", na.strings = "",
header = TRUE, sep = "\t",
colClasses = rep("character", 44), # For simplicity
verbose = TRUE)
如果我删除有问题的行,问题就会消失:
cat(read_problem, file = "temp")
string_vec <- readLines("temp")
clipped_vec <- string_vec[-1027] # Get rid of problem line 1027
restored <- paste(clipped_vec, collapse = "\n")
noerror <- fread(restored, encoding = "UTF-8", na.strings = "",
header = TRUE, sep = "\t",
colClasses = rep("character", 44)) # For simplicity
class(noerror)
[1] "data.table" "data.frame"
dim(noerror)
[1] 1999 44
错误消息似乎很清楚:fread
正在寻找“\t”,但在其位置上找到了其他内容。
但仔细观察违规线相对于周围的线,我发现没有什么明显的。
制表符的个数相同
sapply(gregexpr("\t", string_vec[1026:1028]), length)
[1] 43 43 43
换行符信息似乎相同
unlist(gregexpr("\n", string_vec[1026:1028]))
[1] -1 -1 -1
下面将违规行本身视为一个字符串:
string_vec[1027]
[1] "URN:CornellLabOfOrnithology:EBIRD:OBS132960387\t29816\tspecies\tNelson's Sparrow\tAmmodramus nelsoni\t\t\t1\t\t\tUnited States\tUS\tGeorgia\tUS-GA\tGlynn\tUS-GA-127\tUS-GA_3181\t\t\tJekyll Island\tL140461\tH\t31.0464993\t-81.4113007\t1990-11-03\t13:15:00\t\"Jekyll Island and Causeway. Partly cloudy, mild, NE wind 8-15 mph. Note: Did very little birding in upland habitats as time available was rather brief.\" Data entered on behalf of Paul Sykes by Alison Huff (arhuff@uga.edu) on 12-15-11.\tListed on old Georgia Field Checklist as \"Sparrow, Sharp-tailed.\"\tobsr289931\tPaul\tSykes\tS9336358\teBird - Traveling Count\tEBIRD\t270\t8.047\t\t1\t1\t\t1\t0\t\t"
有什么建议可以在不手动提取违规行的情况下解决这个问题吗?
With with this commit, this is now fixed in v1.9.7,当前开发版本。因此,下一个稳定版本应该能够使用 quote=""
.
正确读取它
require(data.table) #v1.9.7+
fread('"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n', quote="")
# V1 V2 V3
# 1: "abcd efgh." ijkl. mnop "qrst uvwx." 45
第 1027 行,"Sparrow, Sharp-tailed."
末尾只有一个制表符。在其他行中,在该字段之后,在 "obsr[0-9]" 字段开始之前有两个。
制表符的数量似乎匹配,因为在第 1027 行,"Listed on old Georgia Field" 之前有一个制表符而不是 space..
因此第 1027 行只有 43 列而不是 44 列。这似乎是问题所在。
再看一遍,似乎 Listed on old Georgia Field Checklist as "Sparrow, Sharp-tailed."
应该作为一个单独的专栏阅读,而是与上一专栏一起阅读...
这是一个较小的可重现示例:
# note that there are only 2 instead of 3 columns
fread('"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n')
# V1 V2
# 1: abcd efgh." ijkl.\tmnop "qrst uvwx. 45
# add a header column and it returns the same error
fread('a\tb\tc\n"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n')
# Error in fread("a\tb\tc\n\"abcd efgh.\" ijkl.\tmnop \"qrst uvwx.\"\t45\n") :
# Expected sep (' ') but new line, EOF (or other non printing character)
# ends field 1 when detecting types ( first): "abcd efgh." ijkl. mnop
# "qrst uvwx." 45
归档1367.
一个可能的解决方案是:
将所有 CSV 读入一个列表
df<-lapply(csv, 函数(x) read.csv(x, stringsAsFactors = FALSE))
列表中的每个元素代表一个 CSV
- 将列表转换成一个大数据框
df2 <- ldply(df, data.frame)
- 照常使用 grep 删除包含 EOF 的行。
df3<-df2[!grepl("eof", df2$V1),]
其中 V1 是 EOF 所在的列名。
对于 "Expected sep ('|') but new line or EOF ends field 6 on line 8863 when reading data:"
这个错误
您只需在 fread 代码中添加额外的 quote=""
fread(load_file_from_directory, sep = "|",quote="")
我正在使用 data.table::fread
将从(我可以访问的)数据库中导出的几个大型制表符分隔文本文件加载到 R 中。 fread
可以轻松快速地处理大部分文件,但其中一个文件生成定期报告的 fread
错误:
Error in fread(read_problem, encoding = "UTF-8", na.strings = "", header = TRUE, :
Expected sep (' ') but new line or EOF ends field ...
包含违规行的文件的较小版本(2000 行)可在此处获得 (RDS file)。
到目前为止,我是这样尝试诊断问题的:
library(data.table) # I'm using 1.9.7 development (same error with 1.9.6)
read_problem <- readRDS("read_problem.rds")
error <- fread(read_problem, encoding = "UTF-8", na.strings = "",
header = TRUE, sep = "\t",
colClasses = rep("character", 44), # For simplicity
verbose = TRUE)
如果我删除有问题的行,问题就会消失:
cat(read_problem, file = "temp")
string_vec <- readLines("temp")
clipped_vec <- string_vec[-1027] # Get rid of problem line 1027
restored <- paste(clipped_vec, collapse = "\n")
noerror <- fread(restored, encoding = "UTF-8", na.strings = "",
header = TRUE, sep = "\t",
colClasses = rep("character", 44)) # For simplicity
class(noerror)
[1] "data.table" "data.frame"
dim(noerror)
[1] 1999 44
错误消息似乎很清楚:fread
正在寻找“\t”,但在其位置上找到了其他内容。
但仔细观察违规线相对于周围的线,我发现没有什么明显的。
制表符的个数相同
sapply(gregexpr("\t", string_vec[1026:1028]), length)
[1] 43 43 43
换行符信息似乎相同
unlist(gregexpr("\n", string_vec[1026:1028]))
[1] -1 -1 -1
下面将违规行本身视为一个字符串:
string_vec[1027]
[1] "URN:CornellLabOfOrnithology:EBIRD:OBS132960387\t29816\tspecies\tNelson's Sparrow\tAmmodramus nelsoni\t\t\t1\t\t\tUnited States\tUS\tGeorgia\tUS-GA\tGlynn\tUS-GA-127\tUS-GA_3181\t\t\tJekyll Island\tL140461\tH\t31.0464993\t-81.4113007\t1990-11-03\t13:15:00\t\"Jekyll Island and Causeway. Partly cloudy, mild, NE wind 8-15 mph. Note: Did very little birding in upland habitats as time available was rather brief.\" Data entered on behalf of Paul Sykes by Alison Huff (arhuff@uga.edu) on 12-15-11.\tListed on old Georgia Field Checklist as \"Sparrow, Sharp-tailed.\"\tobsr289931\tPaul\tSykes\tS9336358\teBird - Traveling Count\tEBIRD\t270\t8.047\t\t1\t1\t\t1\t0\t\t"
有什么建议可以在不手动提取违规行的情况下解决这个问题吗?
With with this commit, this is now fixed in v1.9.7,当前开发版本。因此,下一个稳定版本应该能够使用 quote=""
.
require(data.table) #v1.9.7+
fread('"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n', quote="")
# V1 V2 V3
# 1: "abcd efgh." ijkl. mnop "qrst uvwx." 45
第 1027 行,"Sparrow, Sharp-tailed."
末尾只有一个制表符。在其他行中,在该字段之后,在 "obsr[0-9]" 字段开始之前有两个。
制表符的数量似乎匹配,因为在第 1027 行,"Listed on old Georgia Field" 之前有一个制表符而不是 space..
因此第 1027 行只有 43 列而不是 44 列。这似乎是问题所在。
再看一遍,似乎 Listed on old Georgia Field Checklist as "Sparrow, Sharp-tailed."
应该作为一个单独的专栏阅读,而是与上一专栏一起阅读...
这是一个较小的可重现示例:
# note that there are only 2 instead of 3 columns
fread('"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n')
# V1 V2
# 1: abcd efgh." ijkl.\tmnop "qrst uvwx. 45
# add a header column and it returns the same error
fread('a\tb\tc\n"abcd efgh." ijkl.\tmnop "qrst uvwx."\t45\n')
# Error in fread("a\tb\tc\n\"abcd efgh.\" ijkl.\tmnop \"qrst uvwx.\"\t45\n") :
# Expected sep (' ') but new line, EOF (or other non printing character)
# ends field 1 when detecting types ( first): "abcd efgh." ijkl. mnop
# "qrst uvwx." 45
归档1367.
一个可能的解决方案是:
将所有 CSV 读入一个列表
df<-lapply(csv, 函数(x) read.csv(x, stringsAsFactors = FALSE))
列表中的每个元素代表一个 CSV
- 将列表转换成一个大数据框
df2 <- ldply(df, data.frame)
- 照常使用 grep 删除包含 EOF 的行。
df3<-df2[!grepl("eof", df2$V1),]
其中 V1 是 EOF 所在的列名。
对于 "Expected sep ('|') but new line or EOF ends field 6 on line 8863 when reading data:"
这个错误您只需在 fread 代码中添加额外的 quote=""
fread(load_file_from_directory, sep = "|",quote="")