2015-06-25 4 views
2

Что у меня: ~ 100 txt файлов, каждый из которых имеет 9 столбцов и> 100 000 строк Что я хочу: Комбинированный файл с двумя столбцами, но все строки. то это должно быть транспонировано для вывода> 100 000 столбцов & 2 ряда.Скопируйте и скопируйте многие файлы набора данных фиксированного формата быстро

Я создал функцию ниже, чтобы систематически проходить через файлы в папке, извлекать нужные данные, а затем после каждого файла объединяться вместе с исходным шаблоном.

Проблема: это отлично работает на моих небольших тестовых файлах, но когда я пытаюсь сделать это на больших файлах, я сталкиваюсь с проблемой выделения памяти. Моего 8 ГБ ОЗУ просто недостаточно, и я предполагаю, что часть этого в том, как я написал свой код.

Мой вопрос: Есть ли способ перебрать файлы, а затем присоединиться ко всем сразу в конце, чтобы сохранить время обработки?

Кроме того, если это неправильное место для размещения такого рода вещей, что является лучшим форумом для ввода кода WIP?

##Script to pull in genotype txt files, transpose them, delete commented rows & 
## & header rows, and then put files together. 

library(plyr) 

## Define function 
Process_Combine_Genotype_Files <- function(
     inputdirectory = "Rdocs/test", outputdirectory = "Rdocs/test", 
     template = "Rdocs/test/template.txt", 
     filetype = ".txt", vars = "" 
     ){ 

## List the files in the directory & put together their path 
     filenames <- list.files(path = inputdirectory, pattern = "*.txt") 
     path <- paste(inputdirectory,filenames, sep="/") 


     combined_data <- read.table(template,header=TRUE, sep="\t") 

## for-loop: for every file in directory, do the following 
     for (file in path){ 

## Read genotype txt file as a data.frame 
       currentfilename <- deparse(substitute(file)) 
       currentfilename <- strsplit(file, "/") 
       currentfilename <- lapply(currentfilename,tail,1) 

       data <- read.table(file, header=TRUE, sep="\t", fill=TRUE) 

       #subset just the first two columns (Probe ID & Call Codes) 
       #will need to modify this for Genotype calls.... 
       data.calls <- data[,1:2] 

       #Change column names & row names 
       colnames(data.calls) <- c("Probe.ID", currentfilename) 
       row.names(data.calls) <- data[,1] 


## Join file to previous data.frame 
       combined_data <- join(combined_data,data.calls,type="full") 


## End for loop 
     } 
## Merge all files 
     combined_transcribed_data <- t(combined_data) 
print(combined_transcribed_data[-1,-1]) 
     outputfile <- paste(outputdirectory,"Genotypes_combined.txt", sep="/")   
     write.table(combined_transcribed_data[-1,-1],outputfile, sep="\t") 

## End function 
} 

Заранее спасибо.

+1

Это может быть легко обработано [fread] (http://www.inside-r.org/packages/cran/data.table/docs/fread) и пакетом 'data.table'. – user227710

ответ

3

Try:

filenames <- list.files(path = inputdirectory, pattern = "*.txt") 
require(data.table) 
data_list <- lapply(filenames,fread, select = c(columns you want to keep)) 

теперь у вас есть список всех вас данных. Предполагая, что все TXT-файлы действительно имеют один и тот же столбец-структуру, которую вы можете объединить их с помощью:

data <- rbindlist(data_list) 

транспонирующих данных:

t(data) 

(Благодаря @Jakob H для select в FREAD)

+1

Я бы предположил, что вы удаляете лишние столбцы при чтении в данных, чтобы занимать меньше места: data_list <- lapply (filenames, function (.file) { fread (.file) [, c (нужны колонки), с = FALSE] } –

+0

Это сработало для меня. К сожалению, моя команда write.table разбивает R Studio, я думаю, потому что мой объединенный файл SO большой. Спасибо! –

+0

@DataMunger мой файл имеет пробелы в заголовках столбцов (" Probe_Set_ID ". Мне не повезло импортировать определенные столбцы из-за этого. Не уверен, есть ли способ использовать ваши советы, когда это так. Я что-то упустил? –

1

Если скорость/рабочая память является проблемой, я бы рекомендовал использовать Unix для слияния. В общем, Unix быстрее R. Кроме того, Unix не требует, чтобы вся информация загружалась в ОЗУ, а читала информацию в кусках. Следовательно, Unix никогда не привязан к памяти. Если вы не знаете Unix, но планируете часто манипулировать большими файлами в будущем, изучите Unix. Он прост в освоении и очень мощный. Я приведу пример с файлами csv.

Генерация CSV файлов в R

for (i in 1:10){ 
    write.csv(matrix(rpois(1e5*10,1),1e5,10), paste0('test',i,'.csv')) 
} 

В Shell (т.е. на Mac)/терминал (т.е. на Linux Box)/Cygwin (т.е. на Windows)

cut -f 2,3 -d , test1.csv > final.csv #obtain column 2 and 3 form test1.csv 
cut -f 2,3 -d , test[2,9].csv test10.csv | sed 1d >> final.csv #removing header in test2.csv onward 

Обратите внимание, если вы установили Rtools, тогда вы можете запустить все эти команды Unix из R с помощью функции system.

Чтобы транспонировать, прочитайте final.csv в R и транспонируйте.

UPDATE:

я приурочил выше код. Требуется .4 сек. для запуска. Следовательно, чтобы сделать это для 100 файлов, а не только 10 файлов, он, скорее всего, примет 4 сек..Я не приурочил R-код, однако, может случиться так, что программа Unix и R имеет схожую производительность, когда есть только 10 файлов, однако с более 100 файлами ваш компьютер, скорее всего, станет привязанным к памяти, и R, скорее всего, сработает ,

+0

Ты совершенно прав. Я работал над улучшением этого с помощью Gywin на окнах и на терминале на моей загрузке Ubuntu. Я знаю, что это не по теме, но какие-нибудь хорошие веб-сайты/учебные пособия для изучения этих компьютерных команд? Я изучаю R & Python через такие места, как Datacamp и Coursera. Спасибо. –

+0

@GaiusAugustus Во-первых, для перебора данных нет необходимости знать много Unix. Например, это не похоже на обучение R. С этим умом, вот некоторые хорошие сообщения в блогах http://bconnelly.net/working-with-csvs-on-the-command-line/ & http://practical-data-science.blogspot.com/2012/09 /basic-unix-shell-commands-for-data.html –

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