2013-02-27 3 views
2

У меня есть модель, которую я хотел бы применить для оценки нового набора данных, хранящегося в CSV. К сожалению, новый набор данных является довольно большим, и на этапе прогнозирования на нем заканчивается память, если я делаю все это сразу. Итак, я хотел бы преобразовать процедуру, которая отлично работала для небольших наборов ниже, в пакетный режим, который обрабатывает 500 строк за раз, затем выводит файл для каждого набранного 500.Преобразование R read.csv в пакет readLines?

Я понимаю из этого ответа (What is a good way to read line-by-line in R?), что я могу использовать readLines для этого. Таким образом, я бы преобразование из:

trainingdata <- as.data.frame(read.csv('in.csv'), stringsAsFactors=F) 
fit <- mymodel(Y~., data=trainingdata) 

newdata <- as.data.frame(read.csv('newstuff.csv'), stringsAsFactors=F) 
preds <- predict(fit,newdata) 
write.csv(preds, file=filename) 

к чему-то вроде:

trainingdata <- as.data.frame(read.csv('in.csv'), stringsAsFactors=F) 
fit <- mymodel(Y~., data=trainingdata) 

con <- file("newstuff.csv", open = "r") 
i = 0 
while (length(mylines <- readLines(con, n = 500, warn = FALSE)) > 0) { 
    i = i+1 
     newdata <- as.data.frame(mylines, stringsAsFactors=F) 
     preds <- predict(fit,newdata) 
     write.csv(preds, file=paste(filename,i,'.csv',sep='')) 
} 
close(con) 

Однако, когда я напечатать mylines объект внутри цикла, он не получает автоматического колонный правильно же way read.csv создает что-то, что --- заголовки все еще беспорядок, и всякая ширина столбца modulo происходит под капотом, который обертывает вектор в объект ncol, не происходит.

Всякий раз, когда я нахожу, что пишу варварские вещи, например, обрезая первую строку, обертывая столбцы, я обычно подозреваю, что у R есть лучший способ сделать что-то. Любые предложения о том, как я могу получить вывод read.csv, образуют соединение readLines csv?

ответ

2

Если вы хотите прочитать свои данные в памяти кусками, используя read.csv, используя аргументыи nrows. В псевдокоде:

read_chunk = function(start, n) { 
    read.csv(file, skip = start, nrows = n) 
} 

start_indices = (0:no_chunks) * chunk_size + 1 
lapply(start_indices, function(x) { 
    dat = read_chunk(x, chunk_size) 
    pred = predict(fit, dat) 
    write.csv(pred) 
    } 

В качестве альтернативы, вы можете поместить данные в базу данных SQLite, и использовать sqlite пакет для запроса данных на куски. См. Также this answer, или сделать рытье с помощью [r] large csv на SO.

+0

Это не сохраняет мои заголовки, верно? – Mittenchops

+0

Кроме того, если я правильно понимаю это: все еще делает это одновременным, а не паршивым, правильным? Если у моего процесса заканчивается память из-за шага установки, я все равно не буду выводить, а не писать первую партию n, вторую партию n и т. Д.? – Mittenchops

+0

'lapply' делает это партиями, каждый раз, когда' read_chunk' вызывается, он используется для разных комбинаций 'start' и' n', поэтому для другого подмножества 'file'. Это не сохраняет информацию заголовка внутри 'read_chunk', но вы можете прочитать заголовок один раз за пределами цикла' lapply', если вам это действительно нужно. –

Смежные вопросы