2013-01-22 10 views
5

Sto cercando di ottenere il conteggio delle istanze di 3 eventi "a" consecutivi, "aaa".corrispondenza regolare su R gregexpr

La stringa comprenderà l'alfabeto inferiore, ad es. "abaaaababaaa"

Ho provato il seguente pezzo di codice. Ma il comportamento non è esattamente quello che sto cercando.

x<-"abaaaababaaa"; 
gregexpr("aaa",x); 

vorrei che la partita di restituire 3 casi del verificarsi "AAA" in contrapposizione a 2.

supponga indicizzazione inizia con 1

  • La prima occorrenza di "aaa" è all'indice 3.
  • Il secondo "aaa" è all'indice 4. (questo non è catturato da gregexpr)
  • La terza occorrenza di "aaa" è all'indice 10.

risposta

6

per catturare le partite si sovrappongono, è possibile utilizzare un lookahead come questo:

gregexpr("a(?=aa)", x, perl=TRUE) 

Tuttavia, le partite sono ormai solo un singolo "a", quindi potrebbe complicare ulteriormente la trasformazione di queste partite, soprattutto se non si è sempre alla ricerca di modelli a lunghezza fissa.

1

So di essere in ritardo, ma ho voluto condividere questa soluzione,

your.string <- "abaaaababaaa" 
nc1 <- nchar(your.string)-1 
x <- unlist(strsplit(your.string, NULL)) 
x2 <- c() 
for (i in 1:nc1) 
x2 <- c(x2, paste(x[i], x[i+1], x[i+2], sep="")) 
cat("ocurrences of <aaa> in <your.string> is,", 
    length(grep("aaa", x2)), "and they are at index", grep("aaa", x2)) 
> ocurrences of <aaa> in <your.string> is, 3 and they are at index 3 4 10 

fortemente ispirato this answer da R-aiuto da Fran.

+0

Questo fa anche il lavoro (up-votato), ma voglio evitare cicli espliciti, le mie stringhe sono piuttosto lunghe. –

+0

@AdityaSihag, potrebbe essere decisamente ottimizzato, volevo solo lanciare questa soluzione anche lì. –

0

Ecco un modo per estrarre tutte le corrispondenze sovrapposte di lunghezza variabile utilizzando gregexpr.

x<-"abaaaababaaa" 
# nest in lookahead + capture group 
# to get all instances of the pattern "(ab)|b" 
matches<-gregexpr('(?=((ab)|b))', x, perl=TRUE) 
# regmatches will reference the match.length attr. to extract the strings 
# so move match length data from 'capture.length' to 'match.length' attr 
attr(matches[[1]], 'match.length') <- as.vector(attr(matches[[1]], 'capture.length')[,1]) 
# extract substrings 
regmatches(x, matches) 
# [[1]] 
# [1] "ab" "b" "ab" "b" "ab" "b" 

Il trucco è quello di circondare il modello in un gruppo di cattura e che catturare il gruppo in un'asserzione lookahead. gregexpr restituirà una lista contenente le posizioni iniziali con un attributo capture.length, una matrice in cui la prima colonna corrisponde alle lunghezze della corrispondenza del primo gruppo di cattura. Se lo converti in un vettore e lo sposti nell'attributo match.length (che è tutti zeri, poiché l'intero pattern era all'interno di un'asserzione lookahead), puoi passarlo a regmatches per estrarre le stringhe.

Come suggerito dal tipo di risultato finale, con alcune modifiche, questo può essere vettorizzato, nel caso in cui x è un elenco di stringhe.

x<-list(s1="abaaaababaaa", s2="ab") 
matches<-gregexpr('(?=((ab)|b))', x, perl=TRUE) 
# make a function that replaces match.length attr with capture.length 
set.match.length<- 
function(x) structure(x, match.length=as.vector(attr(x, 'capture.length')[,1])) 
# set match.length to capture.length for each match object 
matches<-lapply(matches, set.match.length) 
# extract substrings 
mapply(regmatches, x, lapply(matches, list)) 
# $s1 
# [1] "ab" "b" "ab" "b" "ab" "b" 
# 
# $s2 
# [1] "ab" "b" 
Problemi correlati