2017-06-23 122 views
1

我试图导入R(3.4.0)中的text file,它实际上包含4列,但第4列大多是空的,直到第200,000 +行。我用的是FREAD()封装内data.table(版本1.10.4)r - 错误:处理fread(data.table)中的所有列后的文本

fread("test.txt",fill = TRUE, sep = "\t", quote = "", header = FALSE) 

我得到这个错误信息:

Error in fread("test.txt", fill = TRUE, sep = "\t", quote = "", header = FALSE) : 
Expecting 3 cols, but line 258088 contains text after processing all cols. Try again with fill=TRUE. Another reason could be that fread's logic in distinguishing one or more fields having embedded sep=' ' and/or (unescaped) '\n' characters within unbalanced unescaped quotes has failed. If quote='' doesn't help, please file an issue to figure out if the logic could be improved. 

我检查了文件,并有在第二十五万八千零八十八行附加文本第四栏(“8-4”)。

不过,fill = TRUE没有解决这个问题,因为我预期。我认为这可能是fread()不适当地确定列号,因为附加列在文件中发生得非常晚。所以我试过这个:

fread("test.txt", fill = TRUE, header = FALSE, sep = "\t", skip = 250000) 

错误依然存在。另一方面,

fread("test.txt", fill = TRUE, header = FALSE, sep = "\t", skip = 258080) 

这没有错误。

我以为我找到了原因,但是当我通过生成的dummy file测试奇怪的事情发生了:在第二十五万行的第4列

write.table(matrix(c(1:990000), nrow = 330000), "test2.txt", sep = "\t", row.names = FALSE) 

与又多了一个“8-4”由Excel。当FREAD()阅读:

fread("test2.txt", fill = TRUE, header = FALSE, sep = "\t") 

它能正常工作,没有错误消息,这应该表明有些晚了额外的列不一定触发错误。

我也尝试更改编码(“Latin-1”和“UTF-8”)或引号,但都没有帮助。

现在我感到无能为力了,希望我做足了我的功课,并提供可重复的信息。感谢您的帮助。

关于环境保护的信息,我的sessionInfo()是:

R version 3.4.0 (2017-04-21) 
Platform: x86_64-apple-darwin15.6.0 (64-bit) 
Running under: macOS Sierra 10.12.5 

Matrix products: default 
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib 

locale: 
[1] zh_TW.UTF-8/zh_TW.UTF-8/zh_TW.UTF-8/C/zh_TW.UTF-8/zh_TW.UTF-8 

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
    [1] dplyr_0.5.0   purrr_0.2.2.2   readr_1.1.1   tidyr_0.6.3   
    [5] tibble_1.3.3   ggplot2_2.2.1   tidyverse_1.1.1  stringr_1.2.0   
    [9] microbenchmark_1.4-2.1 data.table_1.10.4  

loaded via a namespace (and not attached): 
[1] Rcpp_0.12.11  cellranger_1.1.0 compiler_3.4.0 plyr_1.8.4  forcats_0.2.0 
[6] tools_3.4.0  jsonlite_1.5  lubridate_1.6.0 nlme_3.1-131  gtable_0.2.0  
[11] lattice_0.20-35 rlang_0.1.1  psych_1.7.5  DBI_0.6-1  parallel_3.4.0 
[16] haven_1.0.0  xml2_1.1.1  httr_1.2.1  hms_0.3   grid_3.4.0  
[21] R6_2.2.1   readxl_1.0.0  foreign_0.8-68 reshape2_1.4.2 modelr_0.1.0  
[26] magrittr_1.5  scales_0.4.1  rvest_0.3.2  assertthat_0.2.0 mnormt_1.5-5  
[31] colorspace_1.3-2 stringi_1.1.5 lazyeval_0.2.0 munsell_0.4.3 broom_0.4.2  
+2

我认为解决这个问题的最简单的方法是将头添加到文件的顶部,与标签在你的文件中分离出来的标题。 'fread'默认查看数据的前30行,并使用它来推断它有多少列,所以在第4列中没有数据的情况下,它假定只有3个字段。 – Marius

+0

也许加上'quote =“”' –

+0

我想这不是'fread'或'read.csv'的问题。该文件有问题。每个行的csv应该有相同数量的列,而您的文件不会。您应该处理生成文件的过程,而不是如何导入它。 – nicola

回答

1

其实还有就是你提供这两个文件之间的差异,我认为这是FREAD的不同输出的原因。

第一个文件在第三列之后有一行结束,第258088行除外,其中有第4列,然后是行尾。 (您可以使用'显示所有字符来确认'选项)。

另一方面,第二个文件在所有行中都有一个额外的选项卡,即一个新的空列。 因此,在第一种情况下,fread需要3列,然后找到第4列。相反,在第二个文件中,fread需要4列。

我用fill=TRUE检查了read.table,它对这两个文件都起作用。所以我认为这种做法与fread的fill选项有所不同。

我期望从fill=TRUE,所有行被用来推断列的数量(与计算时间成本)。

在评论中有一些很好的解决方法可以使用。

+0

谢谢你的洞察力!我没有注意到其中的差异。我想这个额外的选项卡可能会被Excel添加,而第一个示例文件是由我们的分析器生成的。使用'fill = TRUE'的read.table()完成它的工作,而我尝试使用'fread()'的原因是我们有一堆这样的代码可以运行,而且更快的导入会有很大的帮助。 –

+1

不客气!我认为它会回报添加一个头,并使用fread,因为正如你所说,你有很多文件,并且你使用read.table很多... – NpT

1

该文件存在问题:如果该表有四列,则在第四列丢失的每行末尾应出现\t

在这种情况下,使用低级方法可能会有更好的运气:逐行读取文件,向没有第四列的每行添加一个\t,将每行分割为\t并收集所有在data.frame。上述大部分工作都是由data.table::tstrsplit函数完成的。尝试是这样的:

f<-readLines("test.txt") 
require(stringr) 
require(data.table) 
a<-data.frame(tstrsplit(f,"\t",type.convert=TRUE,names=TRUE,keep=1:4),stringsAsFactors=FALSE) 
str(a) 
#'data.frame': 273070 obs. of 4 variables: 
# $ V1: num 0 0.002 0.004 0.006 0.008 0.01 0.012 0.014 0.016 0.018 ... 
# $ V2: num -18.7113 -1.2685 0.0768 0.1507 0.1609 ... 
# $ V3: num 0 0 0 0 0 0 0 0 0 0 ... 
# $ V4: chr NA NA NA NA ... 
相关问题