2013-04-09 12 views
36

Ho una lista dei compleanni che sembrano qualcosa di simile:Utilizzando gsub per estrarre stringhe di caratteri prima di uno spazio bianco in R

dob <- c("9/9/43 12:00 AM/PM", "9/17/88 12:00 AM/PM", "11/21/48 12:00 AM/PM") 

voglio afferrare solo la data del calendario da questa variabile (cioè mollare tutto dopo la prima occorrenza dello spazio bianco).

Ecco quello che ho provato finora:

dob.abridged <- substring(dob,1,8) 
dob 
[1] "9/9/43 1" "9/17/88 " "11/21/48" 
dob.abridged <- gsub(" $","", dob.abridged, perl=T) 
> dob.abridged 
[1] "9/9/43 1" "9/17/88" "11/21/48" 

Quindi il mio codice funziona per le date di calendario di lunghezza 6 o 7, ma non la lunghezza 8. Eventuali indicazioni su una regex più efficace da usare con gsub che possono gestire le date del calendario di lunghezza 6, 7 o 8?

Grazie.

risposta

85

Non c'è bisogno di substring, basta usare gsub:

gsub(" .*$", "", dob) 
# [1] "9/9/43" "9/17/88" "11/21/48" 

Uno spazio (), quindi qualsiasi carattere (.) qualsiasi numero di volte (*) fino alla fine della stringa ($). Vedi ?regex per imparare le espressioni regolari.

+2

L'unico consiglio che posso condividere qui è che un 'sub' è sufficiente poiché esiste una sola posizione di fine stringa. –

13

Io uso spesso strsplit per questo tipo di problemi, ma mi è piaciuta la semplice risposta di Romain. Ho pensato che sarebbe stato interessante confrontare la soluzione di Romain ad un strsplit risposta:

Ecco una soluzione strsplit:

sapply(strsplit(dob, "\\s+"), "[", 1) 

Usando il pacchetto microbenchmark e dob <- rep(dob, 1000) con i dati originali:

Unit: milliseconds 
            expr  min  lq median 
        gsub(" .*$", "", dob) 4.228843 4.247969 4.258232 
sapply(strsplit(dob, "\\\\s+"), "[", 1) 14.438241 14.558832 14.634638 
     uq  max neval 
    4.268029 5.081608 1000 
14.756628 53.344984 1000 

Il il chiaro vincitore su una macchina Win 7 è la regex gsub di Romain. Grazie per la risposta e la spiegazione Romain.

1

La libreria stringr contiene una funzione su misura per questo problema.

library(stringr) 
word(dob,1) 
# [1] "9/9/43" "9/17/88" "11/21/48" 
Problemi correlati