读取 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 对出现在中间而不是开头的额外列很挑剔,这就是为什么在这里使用 selectfill 不起作用的原因。你可以做的是把它给你的所有行放在前面,然后在你已经加载的行上再试一次skip。在第二次(或更多)尝试中,额外的列现在将位于开头,因此 fillselect 按预期工作。可能有更优雅的方法来执行以下操作,但这有效

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 &gt; tmp(在unix shell 中)然后fread("tmp") 更容易,效果很好。 您能否使用此命令更新您的答案,以便获得批准。如果你有的话,你也可以分享一下windows CMD的命令吗?

以上是关于读取 R 中列数不固定的文件 fread()的主要内容,如果未能解决你的问题,请参考以下文章

合并两个具有相同列名但在熊猫中列数不同的数据框

Informix:计算临时表中的列数?

如何在 R 中读取具有不同列数的 CSV 文件

以更快的方式计算 R 中列中不同 id 的特征

例外:尽管范围是从数据创建的,但数据中的列数与范围中的列数不匹配

java 操作Excel,循环每一行的列,为啥列数不相同呢。