2016-04-28 65 views
0

我尝试使用下面的代码读取大文件使用laf_open_fwf固定宽度的文件如何管理流氓数据行:在阅读中的R

laf <- laf_open_fwf(paste(input$dir,"/",filename,sep=""), column_widths = col_width, 
          column_types=rep("character",length(col_width)),                  
          column_names = column_names) 

的表现还是不错的,但我的问题是,可以说文件中有大约100,000行数据都符合固定宽度的定义;但在某些情况下,可能会有几行数据“流氓”,因为它们不符合每列的固定宽度 - 某些列中的数据,或者只是说一列可能更长或更短,并且发生这种情况时,这个阅读器的输出完全被破坏了。

我想那是什么被解析之后的第二流氓行解析器遇到的每一个数据线时,无法正确解析。这种情况尤其是当流氓的数据行的最后一列有过多的数据(长于为它定义的宽度)

那么如何解决这个任何想法将不胜感激。

+0

您可能需要使用'readLines()'并自己解析数据。 – Gopala

+0

是的你是对的 - 我遵循这个逻辑,我现在有所有流氓记录的rowNumbers和正确的记录 - 但laf_open_fwf似乎通过打开文件连接工作 - 所以我需要一个文件只有正确的数据。 或者有什么方法可以指定解析器只读取选定的数据行? – Sandeep

+1

不是我能看到的。如果你可以使用一些unix工具来清理这些行并将其清除,最简单。 – Gopala

回答

0

不幸的是,LaF假设所有行具有相同的长度。它使用线条的宽度快速跳到所需的线条。要进入它知道从行的开头到字节(X - 1) * (sum(column_widths) + 1/2)线X(该1/2依赖于EOF行字符使用\n/\r\n)。

唯一的解决办法是从文件中删除了“无赖”线。下面我给出一个纯粹的R如何做到这一点的例子。它速度相当快。

生成,并用〜2%“流氓”线例如文件:

lines <- c("abcde3.14", "efghi-123", "abcdef2.11") 
lines <- sample(lines, 1E6, prob = c(0.44, 0.44, 0.02), replace=TRUE) 
writeLines(lines, "test.dat") 

阅读块写入具有正确长度的一个连接,并且其它线连接到另一连接线的文件。通过外循环打开连接,并保持它们打开,这是相当快的:

widths <- c(5,4) 
types <- c("string", "numeric") 
names <- c("a", "b") 
library(LaF) 


con <- file("test.dat", "rt") 
ok <- file("ok.dat", "wt") 
notok <- file("notok.dat", "wt") 
while (TRUE) { 
    l <- readLines(con, n = 1E5) # increase n for faster reading; used 1E5 as example 
    if (length(l) == 0) break; 
    s <- nchar(l) == sum(widths) 
    writeLines(l[s], con = ok) 
    writeLines(l[!s], con = notok) 
} 
close(notok) 
close(ok) 
close(con) 

用正确的线路则可以通过LaF解析的文件:

laf <- laf_open_fwf("ok.dat", column_types = types, column_names = names, 
    column_widths = widths) 
laf[,] 

,您可以检查其他文件看看错误是什么。