2011-11-23 13 views
6

Ho un vettore composto da voci quali "ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0", e così via, e voglio sottoinsieme questo vettore sulla base di condizioni quali:Come suddividere il vettore in base al carattere stringa?

  1. Il terzo personaggio è un Z
  2. il terzo e il settimo personaggi sono Z
  3. il terzo e il settimo personaggi sono Z, e nessuno degli altri personaggi sono Z

ho provato a giocare con strsplit e grep, ma non riuscivo a capire un modo di limitare le mie condizioni sulla base dei posi zione del carattere sulla corda. Eventuali suggerimenti?

Grazie mille!

+1

I vettori avranno sempre la stessa lunghezza e solo 0, 1s e Z? Non so come funzioni questa roba, potrei solo dargli una regex :) – sinni800

risposta

10

È possibile eseguire questa operazione con espressioni regolari (vedere ?regexp per dettagli sulle espressioni regolari).

grep restituisce il percorso della corrispondenza e restituisce un vettore di lunghezza zero se non viene trovata alcuna corrispondenza. Potresti invece utilizzare grepl, poiché restituisce un vettore logico che puoi utilizzare come sottoinsieme.

z <- c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0") 
# 3rd character is Z ("^" is start of string, "." is any character) 
grep("^..Z", z) 
# 3rd and 7th characters are Z 
grep("^..Z...Z", z) 
# 3rd and 7th characters are Z, no other characters are Z 
# "[]" defines a "character class" and "^" in a character class negates the match 
# "{n}" repeats the preceding match n times, "+" repeats is one or more times 
grep("^[^Z]{2}Z[^Z]{3}Z[^Z]+", z) 
+0

E perché dovresti prendere in considerazione la possibilità di farlo in altro modo? –

+0

Grazie mille per il vostro aiuto. Ho iniziato a giocare con le espressioni regolari e sono ** fantastici **! Non posso credere di non essermi imbattuto in questo prima. Grazie! –

2

È possibile eseguire i primi due senza espressioni regolari utilizzando il comando substr per estrarre caratteri specifici se lo si desidera.

# Grab the third character in each element and compare it to Z 
substr(z, 3, 3) == "Z" 
# Check if the 3rd and 7th characters are both Z 
(substr(z, 3, 3) == "Z") & (substr(z, 7, 7) == "Z") 

Tuttavia, l'approccio espressione regolare Joshua ha dato è più flessibile e cercando di attuare la terza restrizione si ha utilizzando un approccio substr sarebbe un dolore. Le espressioni regolari sono molto più adatte per un problema come la terza restrizione e imparare a usarle non è mai una cattiva idea.

3

Espansione risposta di Josh, si vuole

your_dataset <- data.frame(
    z = c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0") 
) 
regexes <- c("^..Z", "^..Z...Z", "^[^Z]{2}Z[^Z]{3}Z[^Z]+") 

lapply(regexes, function(rx) 
{ 
    subset(your_dataset, grepl(rx, z)) 
}) 

Considera anche sostituendo grepl(rx, z) con str_detect(z, rx), utilizzando il pacchetto stringr. (Non c'è alcuna differenza reale tranne che per un codice leggermente più leggibile.)

+0

Il mio voto riconosce il sottoinsieme (., Grepl (.)) Suggerimento. –

Problemi correlati