2016-04-28 74 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[,] 

,您可以檢查其他文件看看錯誤是什麼。