2011-10-11 30 views
67

Me gustaría hacer algunas caminatas bidimensionales utilizando cadenas de caracteres asignando valores diferentes a cada carácter. Estaba planeando 'explotar' el primer carácter de una cuerda, usarlo y repetirlo por el resto de la cuerda.Obtener y eliminar el primer carácter de una cadena

¿Cómo puedo lograr algo como esto?

x <- 'hello stackoverflow' 

Me gustaría ser capaz de hacer algo como esto:

a <- x.pop[1] 

print(a) 

'h' 
print(x) 

'ello stackoverflow' 

Respuesta

109

Ver ?substring.

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

La idea de tener un método pop que tanto devuelve un valor y tiene un efecto secundario de la actualización de los datos almacenados en x es en gran medida un concepto de programación orientada a objetos. Entonces, en lugar de definir una función pop para operar en vectores de caracteres, podemos hacer un reference class con un método 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

Utilice esta función desde stringi paquete

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

eliminación primeros caracteres:

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

idea es que todos los caracteres a partir del 2 al número de caracteres de x. Esto es importante cuando tiene una cantidad desigual de caracteres en palabra o frase.

Selección de la primera letra es trivial como respuestas anteriores:

substring(x,1,1) 
6

substring es definitivamente mejor, pero aquí hay un strsplit alternativa, ya que no he visto hasta ahora.

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

o equivalentemente

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

Y puede paste el resto de la cadena de nuevo juntos.

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

Hay también str_sub del paquete stringr

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

Otra alternativa es el uso de captura de sub-expresiones con las funciones de expresión regular regmatches y regexec.

# the original example 
x <- 'hello stackoverflow' 

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

Esto devuelve toda la cadena, el primer carácter, y el "estallar" número en una lista de longitud 1.

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

lo que equivale a list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))).Es decir, contiene el conjunto súper de los elementos deseados, así como la cadena completa.


Adición sapply permitirá que este método funcione para un vector de caracteres de longitud> 1.

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

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

Esto devuelve una lista con la cadena completa emparejado como el primer elemento y las subexpresiones coincidentes capturados por () como los siguientes elementos. Por lo tanto, en la expresión regular '(^.)(.*)', (^.) coincide con el primer carácter y (.*) coincide con los caracteres restantes.

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

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

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

Ahora, podemos usar el método de confianza sapply + [ para sacar las subseries deseados.

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

Este es un truco muy bueno, pero creo que se pierde la pregunta. – pedrosaurio

+0

Tendrá que seguir explicando, ya que puede producir el mismo resultado que las otras respuestas. Vea el último bloque de código que usa 'sapply' para la extracción. "hacer estallar" el primer carácter, como se especifica en la pregunta, es una cuestión de repetir este proceso en el vector resultante (mySecondStrings). – lmo

+0

Claro que funciona con la explicación adicional que acaba de agregar, pero aún así me resulta más complicada de lo que debería. – pedrosaurio

Cuestiones relacionadas