2011-10-11 19 views
67

Vorrei fare alcune passeggiate bidimensionali utilizzando stringhe di caratteri assegnando valori diversi a ciascun carattere. Stavo progettando di "far saltare" il primo carattere di una stringa, usarlo e ripetere per il resto della stringa.Ottenere e rimuovere il primo carattere di una stringa

Come posso ottenere qualcosa di simile?

x <- 'hello stackoverflow' 

mi piacerebbe essere in grado di fare qualcosa del genere:

a <- x.pop[1] 

print(a) 

'h' 
print(x) 

'ello stackoverflow' 

risposta

109

Vedi ?substring.

x <- 'hello stackoverflow' 
substring(x, 1, 1) 
## [1] "h" 
substring(x, 2) 
## [1] "ello stackoverflow" 

L'idea di avere un metodo che sia pop restituisce un valore e ha un effetto collaterale di aggiornamento dei dati memorizzati in x è molto un concetto di programmazione orientata agli oggetti. Quindi, piuttosto che definire una funzione pop per operare su vettori di caratteri, possiamo creare un reference class con un metodo pop.

PopStringFactory <- setRefClass(
    "PopString", 
    fields = list(
    x = "character" 
), 
    methods = list(
    initialize = function(x) 
    { 
     x <<- x 
    }, 
    pop = function(n = 1) 
    { 
     if(nchar(x) == 0) 
     { 
     warning("Nothing to pop.") 
     return("") 
     } 
     first <- substring(x, 1, n) 
     x <<- substring(x, n + 1) 
     first 
    } 
) 
) 

x <- PopStringFactory$new("hello stackoverflow") 
x 
## Reference class object of class "PopString" 
## Field "x": 
## [1] "hello stackoverflow" 
replicate(nchar(x$x), x$pop()) 
## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w" 
8

Usare questa funzione da stringi pacchetto

> x <- 'hello stackoverflow' 
> stri_sub(x,2) 
[1] "ello stackoverflow" 
3

rimozione primi caratteri:

x <- 'hello stackoverflow' 
substring(x, 2, nchar(x)) 

idea è che tutti i caratteri a partire dal 2 al numero di caratteri in x. Questo è importante quando hai un numero diverso di caratteri in parole o frasi.

Selezionando la prima lettera è banale come risposte precedenti:

substring(x,1,1) 
6

substring è sicuramente migliore, ma qui è una strsplit alternativa, dal momento che non ho ancora visto uno.

> x <- 'hello stackoverflow' 
> strsplit(x, '')[[1]][1] 
## [1] "h" 

o equivalentemente

> unlist(strsplit(x, ''))[1] 
## [1] "h" 

E si può paste il resto della stringa di nuovo insieme.

> paste0(strsplit(x, '')[[1]][-1], collapse = '') 
## [1] "ello stackoverflow" 
4

C'è anche str_sub dal pacchetto stringr

x <- 'hello stackoverflow' 
str_sub(x, 2) # or 
str_sub(x, 2, str_length(x)) 
[1] "ello stackoverflow" 
1

Un'altra alternativa è quella di utilizzare la cattura sottoespressioni con le funzioni normali di espressione regmatches e regexec.

# the original example 
x <- 'hello stackoverflow' 

# grab the substrings 
myStrings <- regmatches(x, regexec('(^.)(.*)', x)) 

Ciò restituisce l'intera stringa, il primo carattere, e il risultato "spuntato" in una lista di lunghezza 1.

myStrings 
[[1]] 
[1] "hello stackoverflow" "h"     "ello stackoverflow" 

che è equivalente a list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))).Cioè, contiene il super set degli elementi desiderati e la stringa completa.


calcolata sapply permetterà questo metodo di operare per un carattere vettore di lunghezza> 1.

# a slightly more interesting example 
xx <- c('hello stackoverflow', 'right back', 'at yah') 

# grab the substrings 
myStrings <- regmatches(x, regexec('(^.)(.*)', xx)) 

Questo restituisce una lista con la stringa corrispondente come primo elemento e le sottoespressioni corrispondenti catturati dalle () come i seguenti elementi. Quindi nell'espressione regolare '(^.)(.*)', (^.) corrisponde al primo carattere e (.*) corrisponde ai caratteri rimanenti.

myStrings 
[[1]] 
[1] "hello stackoverflow" "h"     "ello stackoverflow" 

[[2]] 
[1] "right back" "r"   "ight back" 

[[3]] 
[1] "at yah" "a"  "t yah" 

Ora, siamo in grado di utilizzare il metodo di fidato sapply + [ per tirare fuori le sottostringhe desiderati.

myFirstStrings <- sapply(myStrings, "[", 2) 
myFirstStrings 
[1] "h" "r" "a" 
mySecondStrings <- sapply(myStrings, "[", 3) 
mySecondStrings 
[1] "ello stackoverflow" "ight back"   "t yah" 
+0

Questo è un trucco molto bello ma penso che manchi la domanda. – pedrosaurio

+0

Sarà necessario spiegare ulteriormente poiché può produrre lo stesso risultato delle altre risposte. Vedi l'ultimo blocco di codice che usa 'sapply' per l'estrazione. "scoppiare" il primo carattere, come specificato nella domanda, è una questione di ripetere questo processo sul vettore risultante (mySecondStrings). – lmo

+0

Certo, funziona con la spiegazione aggiuntiva che hai appena aggiunto, ma la trovo ancora più complessa di quanto dovrebbe. – pedrosaurio

Problemi correlati