2015-01-15 4 views
6

проблема в том, что у меня большой текстовый файл. Пусть это будетСравнить каждый * nd символ текстовой строки

a=c("atcgatcgatcgatcgatcgatcgatcgatcgatcg") 

Мне нужно сравнить каждый 3-й символ в тексте со значением (например, 'c') и если это правда, я хочу добавить 1 противостоять i. Я думал использовать grep, но, похоже, эта функция не подходит для моей цели. Так что мне нужна ваша помощь или совет.

Более того, я хочу извлечь определенные значения из этой строки в вектор. Например, я хочу извлечь 4:10 символов, например.

a=c("atcgatcgatcgatcgatcgatcgatcgatcgatcg") 
[1] "gatcgatcga" 

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

P.S.

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

ответ

1

Сравните каждый третий символ с "c":

grepl("^(.{2}c)*.{0,2}$", a) 
# [1] FALSE 

Извлечение символов 4 до 10:

substr(a, 4, 10) 
# [1] "gatcgat" 
+0

К сожалению, этот код не работает. Если вы посмотрите на строку, вы узнаете, что есть 3 буквы «c», которые соответствуют требованиям. – Lionir

7

отредактирован обеспечить решение, которое быстро для гораздо больших строк:

Если у вас очень длинная строка (порядка миллионов нуклеотидов), утверждение lookbehind в моем o жесткий ответ (см. ниже) слишком медленный, чтобы быть практичным. В этом случае используйте что-то более похожее на следующее: (1) разделяет строку отдельно между каждым символом; (2) использует символы для заполнения трехрядной матрицы; и затем (3) извлекает символы в третьей строке матрицы. Для обработки строки длиной 3 миллиона символов требуется порядка 0,2 секунды.

## Make a 3-million character long string 
a <- paste0(sample(c("a", "t", "c", "g"), 3e6, replace=TRUE), collapse="") 

## Extract the third codon of each triplet 
n3 <- matrix(strsplit(a, "")[[1]], nrow=3)[3,] 

## Check that it works 
sum(n3=="c") 
# [1] 250431 
table(n3) 
# n3 
#  a  c  g  t 
# 250549 250431 249008 250012 

Оригинальный ответ:

я мог бы использовать substr() в обоих случаях.

## Split into codons. (The "lookbehind assertion", "(?<=.{3})" matches at each 
## inter-character location that's preceded by three characters of any type.) 
codons <- strsplit(a, "(?<=.{3})", perl=TRUE)[[1]] 
# [1] "atc" "gat" "cga" "tcg" "atc" "gat" "cga" "tcg" "atc" "gat" "cga" "tcg" 

## Extract 3rd nucleotide in each codon 
n3 <- sapply(codons, function(X) substr(X,3,3)) 
# atc gat cga tcg atc gat cga tcg atc gat cga tcg 
# "c" "t" "a" "g" "c" "t" "a" "g" "c" "t" "a" "g" 

## Count the number of 'c's 
sum(n3=="c") 
# [1] 3 


## Extract nucleotides 4-10 
substr(a, 4,10) 
# [1] "gatcgat" 
+3

И, конечно, если вы собираетесь делать «настоящую работу» с геномными данными, посмотрите проект [Bioconductor] (http: //www.bioconductor.org /) –

+0

Спасибо! А если у меня длинная строка? Будет ли он работать над строкой, например. 1kk символы? Спасибо заранее! – Lionir

+0

Для строки с миллионами символов она будет слишком медленной, поэтому я просто отредактировал ответ, чтобы дать вам еще более быстрое (если не более косвенное) решение. –

3

Это простой подход с использованием R примитивов:

sum("c"==(strsplit(a,NULL))[[1]][c(FALSE,FALSE,TRUE)]) 
[1] 3 # this is the right answer. 

Логического паттерн c(FALSE,FALSE,TRUE) реплицируются быть столь же долго, как входная строка, а затем используется для индексирования его. Его можно настроить в соответствии с другим элементом или для большей длины (для тех, у кого расширенные кодоны).

Вероятно, недостаточно для полноценного генома, но идеально подходит для повседневного использования.

+1

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

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