Extrayendo los últimos n caracteres de una cadena en R

271

¿Cómo puedo obtener los últimos n caracteres de una cadena en R? ¿Hay una función como la DERECHA de SQL?

Brani
fuente

Respuestas:

283

No conozco nada en la base R, pero es sencillo hacer una función para hacer esto usando substry nchar:

x <- "some text in a string"

substrRight <- function(x, n){
  substr(x, nchar(x)-n+1, nchar(x))
}

substrRight(x, 6)
[1] "string"

substrRight(x, 8)
[1] "a string"

Esto está vectorizado, como señala @mdsumner. Considerar:

x <- c("some text in a string", "I really need to learn how to count")
substrRight(x, 6)
[1] "string" " count"
Andrie
fuente
1
Utiliza el paquete stringi. Funciona bien con NA y toda la codificación :)
bartektartanus
¿Sería más eficiente evitar llamar nchar(x)dos veces asignándolo a una variable local?
Dave Jarvis el
206

Si no te importa usar el stringrpaquete, str_subes útil porque puedes usar negativos para contar hacia atrás:

x <- "some text in a string"
str_sub(x,-6,-1)
[1] "string"

O, como Max señala en un comentario a esta respuesta,

str_sub(x, start= -6)
[1] "string"
Xu Wang
fuente
32
Además, str_sub (x, start = -n) obtiene n últimos caracteres.
Max
2
stringr no funciona bien con el valor de NA y toda la codificación. Recomiendo encarecidamente el paquete stringi :)
bartektartanus
3
Creo que se stringrhabía rehecho utilizando stringicomo back-end, por lo que debería funcionar con NA, etc.
m-dz
44

Usar la stri_subfunción del stringipaquete. Para obtener una subcadena desde el final, use números negativos. Mira a continuación los ejemplos:

stri_sub("abcde",1,3)
[1] "abc"
stri_sub("abcde",1,1)
[1] "a"
stri_sub("abcde",-3,-1)
[1] "cde"

Puede instalar este paquete desde github: https://github.com/Rexamine/stringi

Ya está disponible en CRAN, simplemente escriba

install.packages("stringi")

para instalar este paquete

bartektartanus
fuente
20
str = 'This is an example'
n = 7
result = substr(str,(nchar(str)+1)-n,nchar(str))
print(result)

> [1] "example"
> 
Andrés
fuente
12

Otra forma razonablemente sencilla es usar expresiones regulares y sub:

sub('.*(?=.$)', '', string, perl=T)

Entonces, "deshazte de todo seguido de un personaje". Para capturar más caracteres al final, agregue cuantos puntos haya en la afirmación anticipada:

sub('.*(?=.{2}$)', '', string, perl=T)

donde .{2}significa .., o "cualquier dos caracteres", lo que significa "deshacerse de todo seguido de dos caracteres".

sub('.*(?=.{3}$)', '', string, perl=T)

para tres caracteres, etc. Puede establecer el número de caracteres para capturar con una variable, pero deberá pasteingresar el valor de la variable en la cadena de expresión regular:

n = 3
sub(paste('.+(?=.{', n, '})', sep=''), '', string, perl=T)
dsb
fuente
2
Para evitar todas las miradas caprichosas, etc., simplemente podría hacerloregmatches(x, regexpr(".{6}$", x))
thelatemail el
10

ACTUALIZACIÓN : como lo señaló mdsumner , el código original ya está vectorizado porque substr lo es. Debería haber sido más cuidadoso.

Y si quieres una versión vectorizada (basada en el código de Andrie )

substrRight <- function(x, n){
  sapply(x, function(xx)
         substr(xx, (nchar(xx)-n+1), nchar(xx))
         )
}

> substrRight(c("12345","ABCDE"),2)
12345 ABCDE
 "45"  "DE"

Tenga en cuenta que he cambiado (nchar(x)-n)a (nchar(x)-n+1)para obtener npersonajes.

Laurent
fuente
Creo que quieres decir " (nchar(x)-n)a (nchar(x)-n+1)"
Xu Wang
8

Una solución base R simple que usa la substring()función (¿quién sabía que esta función existía?):

RIGHT = function(x,n){
  substring(x,nchar(x)-n+1)
}

Esto aprovecha básicamente ser substr() debajo pero tiene un valor final predeterminado de 1,000,000.

Ejemplos:

> RIGHT('Hello World!',2)
[1] "d!"
> RIGHT('Hello World!',8)
[1] "o World!"
Andrew Haynes
fuente
6

Una alternativa substres dividir la cadena en una lista de caracteres individuales y procesar eso:

N <- 2
sapply(strsplit(x, ""), function(x, n) paste(tail(x, n), collapse = ""), N)
mdsumner
fuente
66
Siento una batalla de system.time (): --)
Carl Witthoft
4

Yo substrtambién lo uso , pero de una manera diferente. Quiero extraer los últimos 6 caracteres de "Dame tu comida". Aquí están los pasos:

(1) Divide los personajes

splits <- strsplit("Give me your food.", split = "")

(2) Extraiga los últimos 6 caracteres.

tail(splits[[1]], n=6)

Salida:

[1] " " "f" "o" "o" "d" "."

Se puede acceder a cada uno de los caracteres splits[[1]][x], donde x es de 1 a 6.

remykarem
fuente
3

alguien antes usa una solución similar a la mía, pero me resulta más fácil pensar de la siguiente manera:

> text<-"some text in a string" # we want to have only the last word "string" with 6 letter
> n<-5 #as the last character will be counted with nchar(), here we discount 1
> substr(x=text,start=nchar(text)-n,stop=nchar(text))

Esto traerá los últimos caracteres como se desee.

JP Fonseca
fuente
3

Prueba esto:

x <- "some text in a string"
n <- 5
substr(x, nchar(x)-n, nchar(x))

Debería dar:

[1] "string"
lukasz
fuente
1

Usé el siguiente código para obtener el último carácter de una cadena.

    substr(output, nchar(stringOfInterest), nchar(stringOfInterest))

Puedes jugar con el nchar (stringOfInterest) para descubrir cómo obtener los últimos caracteres.

Anurag Mishra
fuente
0

Una pequeña modificación en la solución @Andrie también da el complemento:

substrR <- function(x, n) { 
  if(n > 0) substr(x, (nchar(x)-n+1), nchar(x)) else substr(x, 1, (nchar(x)+n))
}
x <- "moSvmC20F.5.rda"
substrR(x,-4)
[1] "moSvmC20F.5"

Eso era lo que estaba buscando. E invita al lado izquierdo:

substrL <- function(x, n){ 
  if(n > 0) substr(x, 1, n) else substr(x, -n+1, nchar(x))
}
substrL(substrR(x,-4),-2)
[1] "SvmC20F.5"
xm1
fuente
0

Por si acaso se necesita elegir un rango de caracteres:

# For example, to get the date part from the string

substrRightRange <- function(x, m, n){substr(x, nchar(x)-m+1, nchar(x)-m+n)}

value <- "REGNDATE:20170526RN" 
substrRightRange(value, 10, 8)

[1] "20170526"
RanonKahn
fuente