Obtener y eliminar el primer carácter de una cadena

102

Me gustaría hacer algunas caminatas bidimensionales usando cadenas de caracteres asignando diferentes valores a cada personaje. Estaba planeando 'hacer estallar' el primer carácter de una cadena, usarlo y repetir para el resto de la cadena.

¿Cómo puedo lograr algo como esto?

x <- 'hello stackoverflow'

Me gustaría poder hacer algo como esto:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'
pedrosaurio
fuente

Respuestas:

167

Ver ?substring.

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

La idea de tener un popmétodo que devuelva un valor y tenga el efecto secundario de actualizar los datos almacenados xes en gran medida un concepto de la programación orientada a objetos. Entonces, en lugar de definir una popfunción para operar en vectores de caracteres, podemos hacer una clase de referencia con un popmétodo.

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"
Richie algodón
fuente
15

También hay str_subdesde el paquete stringr

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

Utilice esta función del stringipaquete

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

substringes definitivamente lo mejor, pero aquí hay una strsplitalternativa, ya que todavía no he visto ninguna.

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

o equivalente

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

Y puedes pastevolver a juntar el resto de la cuerda.

> paste0(strsplit(x, '')[[1]][-1], collapse = '')
## [1] "ello stackoverflow"
Rich Scriven
fuente
5

eliminando los primeros caracteres:

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

La idea es seleccionar todos los caracteres desde 2 hasta el número de caracteres en x. Esto es importante cuando tiene un número desigual de caracteres en una palabra o frase.

Seleccionar la primera letra es trivial como las respuestas anteriores:

substring(x,1,1)
Jon
fuente
2

Otra alternativa es utilizar la captura de sub-expresiones con las funciones de expresión regular regmatchesy regexec.

# the original example
x <- 'hello stackoverflow'

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

Esto devuelve la cadena completa, el primer carácter y el resultado "emergente" en una lista de longitud 1.

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

que es equivalente a list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Es decir, contiene el superconjunto de los elementos deseados, así como la cadena completa.


Agregar sapplypermitirá 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 coincidente como primer elemento y las subexpresiones coincidentes capturadas por ()como los siguientes elementos. Entonces, 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 trusty sapply+ [para extraer las subcadenas deseadas.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"
lmo
fuente
Este es un truco muy bueno, pero creo que no hace la pregunta.
pedrosaurio
Deberá explicar más, ya que puede producir el mismo resultado que las otras respuestas. Vea el bloque final de código que se usa sapplypara 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
Seguro que funciona con la explicación adicional que acaba de agregar, pero todavía lo encuentro más complicado de lo que debería.
pedrosaurio