Extraindo os últimos n caracteres de uma sequência em R

271

Como posso obter os últimos n caracteres de uma string em R? Existe uma função como o DIREITO do SQL?

Brani
fonte

Respostas:

283

Não estou ciente de nada na base R, mas é simples criar uma função para fazer isso usando substre 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"

Isso é vetorizado, como aponta @mdsumner. Considerar:

x <- c("some text in a string", "I really need to learn how to count")
substrRight(x, 6)
[1] "string" " count"
Andrie
fonte
1
Use o pacote stringi. Ele funciona muito bem com Nas e toda a codificação :)
bartektartanus
Seria mais eficiente evitar chamar nchar(x)duas vezes atribuindo-o a uma variável local?
Dave Jarvis
206

Se você não se importa em usar o stringrpacote, str_subé útil porque você pode usar negativos para contar de trás para frente:

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

Ou, como Max aponta em um comentário para esta resposta,

str_sub(x, start= -6)
[1] "string"
Xu Wang
fonte
32
Além disso, str_sub (x, start = -n) obtém n últimos caracteres.
Max
2
stringr não funciona bem com o valor de NA e toda a codificação. Eu recomendo fortemente pacote Stringi :)
bartektartanus
3
Eu acredito que stringrtinha sido refeito usando stringicomo back-end, então deveria trabalhar com NAs etc. agora.
M-dz
44

Use a stri_subfunção do stringipacote. Para obter a substring no final, use números negativos. Veja abaixo os exemplos:

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

Você pode instalar este pacote no github: https://github.com/Rexamine/stringi

Já está disponível no CRAN, basta digitar

install.packages("stringi")

para instalar este pacote.

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

> [1] "example"
> 
Andrew
fonte
12

Outra maneira razoavelmente direta é usar expressões regulares e sub:

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

Então, "livre-se de tudo seguido por um personagem". Para pegar mais caracteres no final, adicione muitos pontos na asserção lookahead:

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

onde .{2}significa .., ou "quaisquer dois caracteres", o que significa "livrar-se de tudo seguido por dois caracteres".

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

para três caracteres, etc. Você pode definir o número de caracteres a serem capturados com uma variável, mas precisará pastedo valor da variável na cadeia de expressão regular:

n = 3
sub(paste('.+(?=.{', n, '})', sep=''), '', string, perl=T)
dsb
fonte
2
Para evitar todo o look-aheads etc, você poderia apenas fazerregmatches(x, regexpr(".{6}$", x))
thelatemail
10

UPDATE : como observado pelo mdsumner , o código original já está vetorizado porque substr é. Deveria ter sido mais cuidadoso.

E se você quiser uma versão vetorizada (com base no 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"

Note que eu mudei (nchar(x)-n)para (nchar(x)-n+1)obter ncaracteres.

Laurent
fonte
Eu acho que você quer dizer " (nchar(x)-n)a (nchar(x)-n+1)"
Xu Wang
8

Uma solução R simples de base usando a substring()função (quem sabia que essa função existia?):

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

Isso tira vantagem de estar basicamente substr()embaixo, mas tem um valor final padrão de 1.000.000.

Exemplos:

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

Uma alternativa substré dividir a sequência em uma lista de caracteres únicos e processar que:

N <- 2
sapply(strsplit(x, ""), function(x, n) paste(tail(x, n), collapse = ""), N)
mdsumner
fonte
6
Sinto uma system.time () batalha de cerveja :-)
Carl Witthoft
4

Eu substrtambém uso , mas de uma maneira diferente. Quero extrair os últimos 6 caracteres de "Me dê sua comida". Aqui estão os passos:

(1) Divida os caracteres

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

(2) Extraia os últimos 6 caracteres

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

Resultado:

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

Cada um dos caracteres pode ser acessado por splits[[1]][x], onde x é 1 a 6.

remykarem
fonte
3

alguém antes usa uma solução semelhante à minha, mas acho mais fácil pensar no seguinte:

> 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))

Isso trará os últimos caracteres conforme desejado.

JP Fonseca
fonte
3

Tente o seguinte:

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

Deveria:

[1] "string"
lukasz
fonte
1

Eu usei o código a seguir para obter o último caractere de uma string.

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

Você pode jogar com o nchar (stringOfInterest) para descobrir como obter os últimos caracteres.

Anurag Mishra
fonte
0

Uma pequena modificação na solução @Andrie também oferece o 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"

Era isso que eu estava procurando. E convida para o lado esquerdo:

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
fonte
0

Apenas no caso de ser necessário escolher um intervalo 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
fonte