2012-05-24 7 views
6

Se ho una stringa e voglio dividere sull'ultima cifra e mantenere l'ultima parte della partizione di hpw posso farlo?diviso sull'ultima occorrenza di cifre, prendere la seconda parte

x <- c("ID", paste0("X", 1:10, state.name[1:10])) 

mi piacerebbe

[1] NA   "Alabama"  "Alaska"  "Arizona"  "Arkansas" 
[6] "California" "Colorado" "Connecticut" "Delaware" "Florida"  
[11] "Georgia"  

Ma accontenterei di:

[1] "ID"   "Alabama"  "Alaska"  "Arizona"  "Arkansas" 
[6] "California" "Colorado" "Connecticut" "Delaware" "Florida"  
[11] "Georgia"  

posso ottenere la prima parte da:

unlist(strsplit(x, "[^0-9]*$")) 

Ma vuole la seconda parte .

Grazie in anticipo.

risposta

2
library(stringr) 
unlist(lapply(str_split(x, "[0-9]"), tail,n=1)) 

[1] "ID"   "Alabama"  "Alaska"  "Arizona"  "Arkansas" "California" "Colorado" "Connecticut" "Delaware" 
[10] "Florida"  "Georgia" 

vorrei guardare la documentazione per stringr (più probabilmente) un approccio ancora migliore.

+0

entrambi eccellenti scelte eri prima. Grazie. –

+3

Si può fare essenzialmente la stessa cosa senza caricare stringr: 'sapply (strsplit (x," [0-9] "), tail, n = 1)' – Dason

+0

@Dason - questa è una soluzione chiara e facilmente comprensibile. Mi dimentico sempre di usare 'tail' e' head' - forse dovrei scrivere qualcosa nel mio file '.First' che dice' "Non dimenticare le funzioni x, y, z - Signed, Me." ' – thelatemail

2

Questo sembra un po 'goffo, ma funziona:

state.pt2 <- unlist(strsplit(x,"^.[0-9]+")) 
state.pt2[state.pt2!=""] 

sarebbe bello per rimuovere le 's "" generati dalla partita all'inizio della stringa, ma non riesco a capirlo.

Ecco un altro metodo che utilizza substr e gregexpr anche che evita di dover sottoinsieme dei risultati:

substr(x,unlist(lapply(gregexpr("[0-9]",x),max))+1,nchar(x)) 
+0

Ben fatto e in base. Sono molto riconoscente. +1 –

+0

Quanto gentile da parte tua! :-D – thelatemail

4

si può fare questo un punto facile con un'espressione regolare:

gsub("(^.*\\d+)(\\w*)", "\\2", x) 

Risultati in:

[1] "ID"   "Alabama"  "Alaska"  "Arizona"  "Arkansas" "California" "Colorado" "Connecticut" 
[9] "Delaware" "Florida"  "Georgia" 

Che la regex fa:

  1. "(^.*\\d+)(\\w*)": Cercare due gruppi di personaggi.
    • Il primo gruppo (^.*\\d+) cerca qualsiasi cifra seguita da almeno un numero all'inizio della stringa.
    • Il secondo gruppo \\w* cerca un carattere alfanumerico.
  2. Il "\\2" come secondo argomento su gsub() significa sostituire la stringa originale con il secondo gruppo rilevato dall'espressione regolare.
+0

Ho anche dimostrato qualcosa di simile con rimodella rinominando i nomi delle colonne. Grazie per avermi ricordato che sono un disastro. Probabilmente la risposta più breve. E una spiegazione formidabile, che manca da molte risposte regex. +1 –

2

gsubfn

provare questa soluzione gsubfn:

> library(gsubfn) 
> strapply(x, ".*\\d(\\w*)|$", ~ if (nchar(z)) z else NA, simplify = TRUE) 
[1] NA   "Alabama"  "Alaska"  "Arizona"  "Arkansas" 
[6] "California" "Colorado" "Connecticut" "Delaware" "Florida"  
[11] "Georgia"  

Si abbina l'ultima cifra seguito da caratteri di parola e restituisce i caratteri di parola o se fallisce corrisponde alla fine della riga (per assicurarsi che corrisponda a qualcosa). Se la prima partita è riuscita, restituiscila; altrimenti, il riferimento all'indietro sarà vuoto, quindi restituisci NA.

Si noti che la formula è un modo breve di scrivere la funzione function(z) if (nchar(z)) z else NA e tale funzione potrebbe sostituire la formula in alternativa, a scapito di un numero leggermente maggiore di sequenze di tasti.

gsub

Una strategia simile potrebbe anche funzionare utilizzando solo dritto gsub ma richiede due linee e una leggermente più complessa espressione regolare. Qui usiamo la seconda alternativa per trangugiare fino non-match dalla prima alternativa:

> s <- gsub(".*\\d(\\w*)|.*", "\\1", x) 
> ifelse(nchar(s), s, NA) 
[1] NA   "Alabama"  "Alaska"  "Arizona"  "Arkansas" 
[6] "California" "Colorado" "Connecticut" "Delaware" "Florida"  
[11] "Georgia"  

EDIT: piccoli miglioramenti

+0

Grazie e per aver inserito l'ND. Molto breve anche +1 –

Problemi correlati