2015-01-15 9 views
6

das Problem ist, ich große Textdatei bekam. Lassen Sie esVergleichen jedes * nd Symbol einer Textzeichenfolge

sein
a=c("atcgatcgatcgatcgatcgatcgatcgatcgatcg") 

ich jedes dritte Symbol in diesem Text mit dem Wert vergleichen müssen (z 'c') und wenn sie wahr ist, ich will 1 hinzufügen i entgegenzuwirken. Ich dachte grep zu verwenden, aber es scheint, diese Funktion für meine Zwecke nicht Hotel würde. Also ich brauche Ihre Hilfe oder Beratung.

Mehr als das, möchte ich bestimmte Werte aus dieser Zeichenfolge in einen Vektor extrahieren. 4 Beispiel, ich möchte 4:10 Symbole, z.

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

Vielen Dank im Voraus.

P.S.

Ich weiß, es ist nicht die beste Idee, Drehbuch, das ich in R schreiben müssen, aber ich bin neugierig, ob sein möglich, sie in angemessener Weise zu schreiben.

Antwort

1

Vergleichen jedes dritte Zeichen mit "c":

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

Extract Zeichen 4 bis 10:

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

Leider funktioniert dieser Code nicht. Wenn Sie auf Zeichenfolge suchen, werden Sie feststellen, dass es drei Buchstaben "c" gibt, die den Anforderungen entsprechen. – Lionir

7

Edited eine Lösung zu schaffen, die für viel größere Saiten schnell ist:

Wenn Sie haben eine sehr lange Zeichenfolge (in der Größenordnung von Millionen von Nukleotiden), die Behauptung in meinem Lookbehind o Die ursprüngliche Antwort (unten) ist zu langsam, um praktisch zu sein. Verwenden Sie in diesem Fall etwas, das dem folgenden ähnelt: (1) teilt die Zeichenfolge zwischen jedem Zeichen auf; (2) verwendet die Zeichen zum Auffüllen einer dreireihigen Matrix; und dann (3) extrahiert die Zeichen in der dritten Zeile der Matrix. Dies dauert in der Größenordnung von 0,2 Sekunden, um eine 3 Millionen Zeichen lange Zeichenfolge zu verarbeiten.

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

Ursprüngliche Antwort:

I substr() in beiden Fällen verwenden können.

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

Und natürlich, wenn Sie viel "echte Arbeit" mit genomischen Daten machen, schauen Sie sich das [Bioconductor-Projekt] (http://www.bioconductor.org) an.org /) –

+0

Danke! Und wenn ich längere Zeichenfolge bekam? Würde es an einer Schnur arbeiten, z.B. 1kk Symbole? Vielen Dank im Voraus! – Lionir

+0

Für eine Zeichenkette mit Millionen von Zeichen ist es zu langsam, also habe ich nur die Antwort bearbeitet, um Ihnen eine weitere, viel schnellere (wenn auch etwas indirekter erscheinende) Lösung zu geben. –

3

Dies ist ein einfacher Ansatz R Primitiven:

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

Die Boolesche Muster c(FALSE,FALSE,TRUE) repliziert, solange die Eingabezeichenfolge zu sein, und dann ist es zu Index verwendet wird. Es kann angepasst werden, um einem anderen Element oder für eine längere Länge zu entsprechen (für diejenigen mit erweiterten Codons).


Wahrscheinlich nicht leistungsfähig genug für ganze Genome, aber perfekt für den gelegentlichen Gebrauch.

+1

Eigentlich scheint ungefähr so ​​schnell wie meine Antwort, plus ein bisschen einfacher in diesem speziellen Fall. –

Verwandte Themen