读取 R 中列数不固定的文件 fread()
Posted
技术标签:
【中文标题】读取 R 中列数不固定的文件 fread()【英文标题】:Reading a file that has non fixed number of columns fread() in R 【发布时间】:2022-01-13 12:24:14 【问题描述】:我正在尝试读取默认情况下应该有 7 列的文件,但可能在某些字符串中可能有一些逗号导致其他行有超过 7 列。
不管其他列中有哪些信息,我唯一的目标是阅读前 7 列。但是,即使添加了参数select = 1:7
,fread 也不会读取整个文件
> data <- fread("dpp.DAT",header=FALSE, fill=T, select = 1:7, sep=", ",stringsAsFactors = F)
Warning message:
In fread("dpp.DAT", header = FALSE, fill=T, select = 1:7,sep = ",", stringsAsFactors = F) :
Stopped early on line 45922. Expected 7 fields but found 8. Consider fill=TRUE and comment.char=. First discarded non-empty line: <<84172666,DS,BRAND 4 - DERIVATIVE,#PL LOC BDD : BDD - BRAND 3 - DERIVATIVE,37324,BLEND-A-MD-INSPRD-BY-NTR-SGHH,BLEND B MAR INSPIRED BY OTHER CHAMOMILE, VAG + HHHH>>
您可以建议读取文件的所有行吗?
Sample dataset
【问题讨论】:
【参考方案1】:Dean 的回答提供了比我更多的自动化。每当我遇到这个问题(实际上可能是格式不正确的数据)时,我都会求助于手动查找然后使用 rbind 重建提取:
s1 <- fread("Extract.txt",
nrows=674170,
strip.white = TRUE,
fill = TRUE,
blank.lines.skip = TRUE,
encoding="UTF-8")
s2 <- fread("Extract.txt",
strip.white = TRUE,
fill = TRUE,
blank.lines.skip = TRUE,
skip=674170,
encoding="UTF-8")
# ad.infinitum until you complete "Extract.txt"
s3 <- rbind(s1,s2)
rm(s1)
rm(s2)
【讨论】:
【参考方案2】:data.table
对出现在中间而不是开头的额外列很挑剔,这就是为什么在这里使用 select
和 fill
不起作用的原因。你可以做的是把它给你的所有行放在前面,然后在你已经加载的行上再试一次skip
。在第二次(或更多)尝试中,额外的列现在将位于开头,因此 fill
和 select
按预期工作。可能有更优雅的方法来执行以下操作,但这有效
library(data.table)
#capture warnings so we can evaluate what happened last in code
tempfile='tmp321364.txt'
conn<-file(tempfile, open="r+")
sink(file=conn, type='message')
DT<-list()
while(TRUE)
DT[[length(DT)+1]] <- fread(filename, header=FALSE,stringsAsFactors = F, fill=T, select=1:7, skip=ifelse(length(DT)>0,sum(sapply(DT, nrow)),0))
if(nrow(DT[[length(DT)]])==0) break
warns<-readLines(conn)
if(length(warns)==3) #The warning about extra columns is 3 lines long
DT[[length(DT)+1]]<- fread(filename, header=FALSE,stringsAsFactors = F, fill=T, select=1:7, skip=sum(sapply(DT, nrow)))
if(nrow(DT[[length(DT)]])==0) break
else #an error about skipping too many rows is not 3 lines, assuming away other issues
break
DT<-rbindlist(DT)
sink(NULL, type='message')
close(conn)
rm(tempfile)
使用您的确切数据,您不需要 while(TRUE)
循环,但例如,如果有第 10 列显示在更下方,那么这将适用于这些情况。
【讨论】:
【参考方案3】:假设我们有一个文本文件"test.txt"
,如下所示:
a,b,c
d,e,f
g,h,i,j
k,l,m
我们可以读入并设置FILL=T
,然后将最后一列子集化出来:
> fread("test.txt", fill=T)[,-4]
V1 V2 V3
1: a b c
2: d e f
3: g h i
4: k l m
或者,设置select=1:3
:
> fread("test.txt", fill=T, select = 1:3)
V1 V2 V3
1: a b c
2: d e f
3: g h i
4: k l m
编辑
解决方案是这样使用cut
unix 命令:
terminal$ cut Test_Fread_column.DAT -d',' -f1-7 > tmp
R> fread("tmp")
【讨论】:
我忘了在问题中提及,但我已经尝试提供参数fill=T
但我仍然遇到同样的错误
@Macosso 除非您提供数据样本,否则这可能很难解决。你能发布一个减少的数据子集,包括违规行吗?
可以使用下面的数据集来测试github.com/Macosso/Test_R_fread
好的。只做cut Test_Fread_column.DAT -d',' -f1-7 > tmp
(在unix shell 中)然后fread("tmp")
更容易,效果很好。
您能否使用此命令更新您的答案,以便获得批准。如果你有的话,你也可以分享一下windows CMD的命令吗?以上是关于读取 R 中列数不固定的文件 fread()的主要内容,如果未能解决你的问题,请参考以下文章