将文件批量加载到 R,同时使用 'sqldf' 排除坏行

Batch load files to R while excluding bad rows using 'sqldf'

我有一大块 R 代码,可以递归加载、整理和导出目录中的所有 .txt 文件(文件是 tab-delimited,但我使用 read.fwf 删除列)。该代码适用于在 9 行不必要的 header 之后具有完整数据的 .txt 文件。但是,当我将代码扩展到包含全套 .txt 文件(>500)的目录时,我发现一些文件的数据中嵌入了坏行(本质上,自动重复了一些 header行,样本可用 here)。我尝试只加载所有行,包括好行和坏行,目的是从 R 中删除坏行,但得到有关列号的错误消息。

原始错误:使用read.fwf批量加载(注意:我只需要每个.txt文件的前三列)

setwd("C:/Users/Seth/Documents/testdata")  
library(stringr)
filesToProcess <- dir(pattern="*.txt", full.names=T)

listoffiles <- lapply(filesToProcess, function(x) read.fwf (x,skip=9, widths=c(10,20,21), col.names=c("Point",NA,"Location",NA,"Time"), stringsAsFactors=FALSE))
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  : 
  line 344 did not have 5 elements    #error from bad rows

接下来我尝试 pre-processing 使用 'sqldf' 排除坏行的数据。

修复尝试 1:使用 'sqldf'

批处理 pre-process
library(sqldf)
listoffiles <- lapply(filesToProcess, function(x) read.csv.sql(x, sep="\t", 
+ skip=9,field.types=c("Point","Location","Time","V4","V5","V6","V7","V8","V9"),
+ header=F, sql = "select * from file where Point = 'Trackpoint' "))
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  : 
  line 1 did not have 9 elements

修复尝试 2:单个文件 pre-process 使用 'sqldf'

test.v1 <- read.csv.sql("C:/Users/Seth/Documents/testdata/test/2008NOV28_MORNING_Hunknown.txt", 
+ sep="\t", skip=9,field.types=c("Point","Location","Time","V4","V5","V6","V7","V8","V9"),
+ header=F, sql = "select * from file where Point = 'Trackpoint' ")
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  : 
  line 1 did not have 9 elements

我更愿意干净利落地使用 'sqldf' 或 'dplyr 之类的东西,但我愿意拉入所有行,然后在 R 中 post-process。我的问题:我如何在导入过程中排除坏数据行?或者,如何导入完整的数据集,然后删除 R 中的坏行?

这里有几种方法。它们都利用了这样一个事实,即好行都包含度数符号(八进制 260),而垃圾行则没有。在所有这些中,我们假设要删除第 1 列和第 3 列。

1) 此代码假定您有 grep 但您可能需要引用 grep 的第一个参数,具体取决于您的 shell . (在 Windows 上,要获得 grep,您需要安装 Rtools,而在正常的 Rtools 安装下,grep 可在此处找到:C:\Rtools\bin\grep.exe。Rtools bin 目录必须放在您的 Windows 路径上,否则在引用 Rtools grep 时需要使用整个路径名。)这些注释仅适用于 (1) 和 (4),如 (2) 和 (3)不要使用系统的grep。

File <- "2008NOV28_MORNING_trunc.txt"

library(sqldf)
DF <- read.csv.sql(File, header = FALSE, sep = "\t", eol = "\n",
       sql = "select V2, V4, V5, V6, V7, V8, V9 from file",
       filter = "grep [0] ")

2) 你可能不需要 sqldf:

DF <- read.table(text = grep("0", readLines(File), value = TRUE), 
        sep = "\t", as.is = TRUE)[-c(1, 3)]

3) 或者尝试以下比 (2) 更有效但涉及指定 colClasses 向量:

colClasses <- c("NULL", NA, "NULL", NA, NA, NA, NA, NA, NA)
DF <- read.table(text = grep("0", readLines(File), value = TRUE), 
        sep = "\t", as.is = TRUE, colClasses = colClasses)

4)我们也可以用系统的grep和`read.table。 (1) 中关于 grep 的评论也适用于此:

DF <- read.table(pipe(paste("grep [0]", File)), 
        sep = "\t", as.is = TRUE, colClasses = colClasses)