2015-10-08 1 views
1

У меня есть фрагмент кода R, который рекурсивно загружает, упорядочивает и экспортирует все .txt-файлы в каталог (файлы разделены табуляцией, но я использовал read.fwf для удаления столбцов). Код работает для файлов .txt с полными данными после 9 строк ненужных заголовков. Однако, когда я расширил код до каталога с полным набором файлов .txt (> 500), я обнаружил, что некоторые из файлов имеют плохие строки, встроенные в данные (по существу, автоматические повторы нескольких строк заголовков, выборки доступны here). Я попытался просто загрузить все строки, как хорошие, так и плохие, с целью удаления плохих строк из R, но получить сообщения об ошибках о номерах столбцов.Пакетная загрузка файлов в R, исключая неудачные строки с использованием sqldf

Оригинальная ошибка: Пакетная загрузка с помощью 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 

Далее я попытался предварительной обработки данных, чтобы исключить плохие строки с использованием 'sqldf'.

Fix попытка 1: Пакетное предварительной обработки с использованием '' sqldf

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 

Fix попытка 2: Один файл предварительной обработки с использованием '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. Мои вопросы: Как исключить неверные строки данных во время импорта? Или, как мне получить полный набор данных, импортированных, а затем удалить плохие строки внутри R?

+1

Вы должны понимать, что тег 'batch-file' имеет _no_ отношение к вашей проблеме и удаляет его ... – Aacini

+0

Спасибо, @Aacini. Было предложено Стеком, и я ошибался, чтобы включить его. –

+0

'read.sql.csv' поддерживает ключевое слово' filter = '. См. '? Read.csv.sql' и'? Sqldf''. –

ответ

2

Вот несколько способов. Все они используют тот факт, что хорошие строки содержат символ степени (октал 260), а нежелательные линии - нет. Во всех этих случаях мы предположили, что столбцы 1 и 3 должны быть отброшены.

1) Этот код предполагает, что вы grep, но вы, возможно, придется процитировать первый аргумент grep в зависимости от оболочки. (В Windows, чтобы получить grep, вам нужно будет установить Rtools, а при обычной установке Rtools grep можно найти здесь: C:\\Rtools\bin\grep.exe. Каталог bin Rtools должен быть помещен на ваш путь к 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 [\260] ") 

2) Вам не нужно sqldf для этого:

DF <- read.table(text = grep("\260", 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("\260", readLines(File), value = TRUE), 
     sep = "\t", as.is = TRUE, colClasses = colClasses) 

4) Мы также можем использовать grep системы с `read.table. Здесь также приводятся комментарии в (1) о grep:

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

Большое спасибо @ G.Grothendieck! Они решили мою проблему! –