R中read.table读取制表符分隔数据异常问题求助
制表符分隔数据读取异常问题排查与解决
我用以下R代码读取制表符分隔的数据(数据下载需耗时数秒):
library(dplyr) mydata <- "https://pxdata.stat.fi:443/PxWeb/sq/87e44319-48f8-41b4-bd0d-a6629dc7829c" %>% paste0(".relational_table") %>% read.table(sep = "\t", header = T)
部分数据行解析正常,示例如下:
> head(mydata) Underlying.cause.of.death..ICD.10..3.character.level. Age Year Sex Information Deaths 1 A00-Y89 Total Total 2022 Total Deaths 63172 2 A00-Y89 Total Total 2022 Males Deaths 31703 3 A00-Y89 Total Total 2022 Females Deaths 31469 4 A00-Y89 Total 0 2022 Total Deaths 91 5 A00-Y89 Total 0 2022 Males Deaths 52 6 A00-Y89 Total 0 2022 Females Deaths 39
但有部分行解析异常,字段内容混入其他行,示例如下:
> mydata %>% filter(grepl("\t",Underlying.cause.of.death..ICD.10..3.character.level.)) %>% head Underlying.cause.of.death..ICD.10..3.character.level. Age Year Sex Information Deaths 1 A30 Leprosy (Hansens disease)\tTotal\t2022\tTotal\tDeaths\t0\nA30 Leprosy (Hansens disease) Total 2022 Males Deaths 0 2 A30 Leprosy (Hansens disease)\tTotal\t2022\tFemales\tDeaths\t0\nA30 Leprosy (Hansens disease) 0 2022 Total Deaths 0 3 A30 Leprosy (Hansens disease)\t0\t2022\tMales\tDeaths\t0\nA30 Leprosy (Hansens disease) 0 2022 Females Deaths 0 4 A30 Leprosy (Hansens disease)\t1 - 4\t2022\tTotal\tDeaths\t0\nA30 Leprosy (Hansens disease) 1 - 4 2022 Males Deaths 0 5 A30 Leprosy (Hansens disease)\t1 - 4\t2022\tFemales\tDeaths\t0\nA30 Leprosy (Hansens disease) 5 - 9 2022 Total Deaths 0 6 A30 Leprosy (Hansens disease)\t5 - 9\t2022\tMales\tDeaths\t0\nA30 Leprosy (Hansens disease) 5 - 9 2022 Females Deaths 0
疑问
明明指定了sep="\t"作为列分隔符,为什么还是会出现部分行数据未正确拆分、字段内容混入其他行的情况?有没有更合适的函数可以正确读取该数据?(我使用Windows 10系统)
问题原因
核心原因是数据文件的换行符格式不统一,或者read.table默认的换行符识别逻辑与文件实际情况不匹配。从异常行内容能看到字段中包含\n(换行符),说明本该作为行分隔的换行符被误判为字段内容的一部分,导致read.table没有正确拆分行,进而将多行数据错误合并到同一行的字段里。
另外,read.table对复杂文本的特殊字符容错性较弱,当字段内容意外包含分隔符或换行符时,很容易出现解析混乱。
解决方案
推荐以下几种更可靠的读取方式:
1. 使用readr包的read_tsv函数
readr包的读取工具对文本格式兼容性更好,默认能自动识别不同系统的换行符,处理特殊字符的逻辑更稳健:
library(dplyr) library(readr) url <- "https://pxdata.stat.fi:443/PxWeb/sq/87e44319-48f8-41b4-bd0d-a6629dc7829c.relational_table" mydata <- read_tsv(url)
2. 手动指定参数优化read.table
如果坚持使用基础包的read.table,可以显式指定换行符、编码等参数:
library(dplyr) url <- "https://pxdata.stat.fi:443/PxWeb/sq/87e44319-48f8-41b4-bd0d-a6629dc7829c.relational_table" mydata <- read.table(url, sep = "\t", header = TRUE, fileEncoding = "UTF-8", quote = "")
其中quote = ""可避免将换行符识别为引号内的内容,fileEncoding = "UTF-8"确保Windows系统下编码识别正确。
3. 使用data.table包的fread函数
data.table的fread以速度快、容错性强著称,能自动识别分隔符、换行符和编码:
library(dplyr) library(data.table) url <- "https://pxdata.stat.fi:443/PxWeb/sq/87e44319-48f8-41b4-bd0d-a6629dc7829c.relational_table" mydata <- fread(url)
内容的提问来源于stack exchange,提问作者Aku-Ville Lehtimäki
相关产品推荐
相关产品推荐

