2015-01-15 16 views
6

il problema è che ho un grande file di testo. Lascia che siaConfronta ogni * nd simbolo di una stringa di testo

a=c("atcgatcgatcgatcgatcgatcgatcgatcgatcg") 

ho bisogno di confrontare ogni 3 simbolo in questo testo con un valore (ad esempio 'c') e se è vero, voglio aggiungere 1 per contrastare i. Ho pensato di usare grep ma sembra che questa funzione non sarebbe adatta al mio scopo. Quindi ho bisogno del tuo aiuto o consiglio.

Oltre a ciò, voglio estrarre determinati valori da questa stringa a un vettore. 4 esempio, voglio estrarre i simboli 4:10, ad es.

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

Grazie in anticipo.

P.S.

So che non è la migliore idea per scrivere script di cui ho bisogno in R, ma sono curioso di sapere se è possibile scriverlo in modo adeguato.

risposta

1

Confronta ogni terzo personaggio con "c":

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

caratteri Estratto da 4 a 10:

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

Purtroppo questo codice non funziona. Se guardi sullo spago, scoprirai che ci sono 3 lettere "c" che soddisfano i requisiti. – Lionir

7

A cura di fornire una soluzione che è veloce per le stringhe molto più grandi:

Se hai una stringa molto lunga (dell'ordine di milioni di nucleotidi), l'affermazione del look-behind nella mia o la risposta originale (sotto) è troppo lenta per essere pratica. In tal caso, usa qualcosa di più simile al seguente, che: (1) divide la corda tra ogni personaggio; (2) usa i caratteri per riempire una matrice a tre righe; e quindi (3) estrae i caratteri nella terza riga della matrice. Questo richiede l'ordine di 0,2 secondi per elaborare una stringa lunga 3 milioni di caratteri.

## 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 

risposta originale:

potrei usare substr() in entrambi i casi.

## 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

E, naturalmente, se hai intenzione di fare molto "vero lavoro" con i dati genomici, controlla il [progetto Bioconductor] (http: //www.bioconductor.org /) –

+0

Grazie! E se avessi una stringa più lunga? Funzionerebbe su una stringa, ad es. Simboli 1kk? Grazie in anticipo! – Lionir

+0

Per una stringa con milioni di caratteri, sarà troppo lento, quindi ho appena modificato la risposta per darvi un'altra soluzione molto più veloce (se in qualche modo più indiretta). –

3

Questo è un approccio semplice mediante primitive R:

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

Il modello booleano c(FALSE,FALSE,TRUE) viene replicato essere lungo quanto la stringa di input e quindi viene utilizzato per indicizzare esso. Può essere regolato per abbinare un elemento diverso o per una lunghezza maggiore (per quelli con codoni estesi).


Probabilmente non abbastanza performante per interi genomi, ma perfetto per uso occasionale.

+1

In realtà sembra altrettanto veloce della mia risposta, più un po 'più semplice in questo caso particolare. –

Problemi correlati