2015-04-08 4 views
1

У меня есть файл с 800000 строк и 13000 столбцов. Файл выглядит следующим образом:Замена уровней факторов более эффективно в огромном файле

 ID1 ID2 ID3 ID4 ID5 
SNP1 AA AA AB AA BB 
SNP2 AB AA BB AA AA 
SNP3 BB BB BB AB BB 
SNP4 AA AA BB BB AA 
SNP5 AA AA AA AA AA 

Я хочу заменить буквы цифрами (АА = 0, АВ = 1 и BB = 2). Что я сделал: данные [данные == "AA"] = 0 Кажется, что он работает отлично в небольшом примере, но он, похоже, не выполняет эту работу в большом файле. Это заняло много времени. Есть ли более эффективный способ сделать это? спасибо. Paula.

+1

С данными такого размера у вас может возникнуть проблема с импортом в R. Возможно, использование некоторых инструментов командной строки, таких как 'sed', может быть намного быстрее. Кроме того, посмотрели ли вы на Bioconductor, если вы работаете с данными генома? – thelatemail

+1

...или редактор, например 'EmEditor', если вы работаете в Windows. Это не бесплатно, а бесплатный пробный период. Он отлично справляется с этими ситуациями. –

ответ

2

файла, скорее всего, слишком большой для R, un меньше вы используете scan, что сильно усложняет работу ИМО. Это работа, которая лучше справляется с использованием утилит GNU.

Если вы в Windows, установите MSYS:

http://www.mingw.org/wiki/Getting_Started

Затем используйте sed как уже упоминалось, чтобы заменить текст:

cat <filename> | sed "s/\bAA\b/0/g" | sed "s/\bBA\b/1/g" | sed "s/\bAB\b/1/g" | sed "s/\bBB\b/2/g" > <newfile> 

Edit:

Если вы должны использовать R, вам, вероятно, придется читать файл по очереди, так как файл содержит ~ 10 миллиардов записей, каждый из 3-х символов - очень большой набор данных!

См SO нить здесь для чтения файла построчно линии:

reading a text file in R line by line

Однако, я подозреваю, что это будет очень медленным.

+0

Большое спасибо @Vince. Я использую Linux, и команда sed отлично работает. Вы не представляете, как вы мне помогли. Еще раз спасибо. – PaulaF

2

Возможно попробовать это:

Читайте в ваших данных:

DF <- read.table(text = "ID1 ID2 ID3 ID4 ID5 
SNP1 AA AA AB AA BB 
SNP2 AB AA BB AA AA 
SNP3 BB BB BB AB BB 
SNP4 AA AA BB BB AA 
SNP5 AA AA AA AA AA 
", header = TRUE, sep = "", stringsAsFactors = FALSE) 

> str(DF) 
'data.frame': 5 obs. of 5 variables: 
$ ID1: chr "AA" "AB" "BB" "AA" ... 
$ ID2: chr "AA" "AA" "BB" "AA" ... 
$ ID3: chr "AB" "BB" "BB" "BB" ... 
$ ID4: chr "AA" "AA" "AB" "BB" ... 
$ ID5: chr "BB" "AA" "BB" "AA" ... 

Создание таблицы поиска:

tab <- c("AA" = 0, "AB" = 1 , "BB" = 2) 
> tab 
AA AB BB 
0 1 2 

Некоторые subassignment магия:

> DF[] <- tab[as.matrix(DF)] 
> DF 
    ID1 ID2 ID3 ID4 ID5 
SNP1 0 0 1 0 2 
SNP2 1 0 2 0 0 
SNP3 2 2 2 1 2 
SNP4 0 0 2 2 0 
SNP5 0 0 0 0 0 
> str(DF) 
'data.frame': 5 obs. of 5 variables: 
$ ID1: num 0 1 2 0 0 
$ ID2: num 0 0 2 0 0 
$ ID3: num 1 2 2 2 0 
$ ID4: num 0 0 1 2 0 
$ ID5: num 2 0 2 0 0 
+0

большое спасибо. Он работает в небольшом наборе данных, но когда я обращаюсь ко всему файлу, я получаю ошибку: Ошибка: длинные векторы еще не поддерживаются: memory.c: 1093 – PaulaF

+1

@PaulaF Я только что заметил, что вы говорите о 800 000 * 13 000 = 10 400 000 000 = 10 млрд. Записей. Я думаю, что такого рода вещи требуют инструментов «большого объема данных» R, таких как те, которые описаны в http://cran.r-project.org/web/views/HighPerformanceComputing.html. Также попробуйте сделать ошибку в своей ошибке и посмотреть, что получится. Возможно, у кого-то есть лучшее решение для экономии памяти. –

+0

большое спасибо. – PaulaF

1

Предполагая, что вам удалось открыть файл и при условии, что это data.frame с factor столбцов, вы можете использовать тот факт, что факторы уже числовые столбцы, пронумерованных от 1:

DF <- read.table(text = "ID1 ID2 ID3 ID4 ID5 
SNP1 AA AA AB AA BB 
SNP2 AB AA BB AA AA 
SNP3 BB BB BB AB BB 
SNP4 AA AB BB BB AA 
SNP5 AA AA AA AA AA 
", header = TRUE, sep = "") 

for (i in seq_along(DF)) { 
    # check if the column levels are ordered correctly; if not 
    # relevel the column 
    if (!identical(levels(DF[[i]]), c("AA", "AB", "BB"))) { 
    warning("Levels do not match in column ", i, ". Relevelling.") 
    DF[[i]] <- factor(DF[[i]], levels=c("AA", "AB", "BB")) 
    } 
    # remove the class of the column: this basically makes an integer 
    # column from the factor 
    attr(DF[[i]], "class") <- NULL 
    # substract 1 to get number from 0 
    DF[[i]] <- DF[[i]] - 1 
} 

проверяет код, если уровни нумеруются правильно и при необходимости сбрасываются. Надеюсь, этого не происходит часто, так как это замедлит работу.

Возможно, ваш файл не вписывается в память, что приведет к тому, что Windows/Linux/... будет использовать диск для хранения данных. Это значительно замедлит работу. В этом случае вам, вероятно, лучше использовать такие пакеты, как ff или bigmemory.

+0

Большое спасибо @ JanvanderLaan. – PaulaF

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