Wyodrębnianie ostatnich n znaków z ciągu w R


271

Jak mogę uzyskać ostatnie n znaków z ciągu w R? Czy istnieje funkcja taka jak PRAWO SQL?

Odpowiedzi:


282

Nic mi nie wiadomo w bazie R, ale łatwo jest zrobić funkcję za pomocą substri 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"

Jest to wektoryzowane, jak wskazuje @mdsumner. Rozważać:

x <- c("some text in a string", "I really need to learn how to count")
substrRight(x, 6)
[1] "string" " count"

1
Użyj pakietu stringi. Działa dobrze z NA i całym kodowaniem :)
bartektartanus

Czy bardziej efektywne byłoby uniknięcie nchar(x)dwukrotnego wywołania poprzez przypisanie go do zmiennej lokalnej?
Dave Jarvis,

206

Jeśli nie masz nic przeciwko korzystaniu z stringrpakietu, str_subjest to przydatne, ponieważ możesz użyć negatywów do liczenia wstecz:

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

Lub, jak wskazuje Max w komentarzu do tej odpowiedzi,

str_sub(x, start= -6)
[1] "string"

32
również str_sub (x, start = -n) dostaje n ostatnich znaków.
Max

2
stringr nie działa dobrze z wartością NA i całym kodowaniem. Zdecydowanie polecam pakiet stringi :)
bartektartanus

3
Wydaje mi się, stringrże został przerobiony stringina backend, więc powinien działać teraz z NA itp.
m-dz

44

Użyj stri_subfunkcji z stringipakietu. Aby uzyskać podciąg od końca, użyj liczb ujemnych. Przykłady poniżej:

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

Możesz zainstalować ten pakiet z github: https://github.com/Rexamine/stringi

Jest już dostępny w CRAN, po prostu wpisz

install.packages("stringi")

aby zainstalować ten pakiet.


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

> [1] "example"
> 

12

Innym dość prostym sposobem jest użycie wyrażeń regularnych i sub:

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

Tak więc „pozbyć się wszystkiego, a następnie jednej postaci”. Aby złapać więcej postaci od końca, dodaj jednak tyle kropek w twierdzeniu lookahead:

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

gdzie .{2}oznacza .., lub „dowolne dwa znaki”, co oznacza „pozbądź się wszystkiego, a po nim dwa znaki”.

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

dla trzech znaków itp. Możesz ustawić liczbę znaków, które mają być pobierane za pomocą zmiennej, ale musisz wprowadzić pastewartość zmiennej do ciągu wyrażenia regularnego:

n = 3
sub(paste('.+(?=.{', n, '})', sep=''), '', string, perl=T)

2
Aby uniknąć wszystkich perspektyw, itp., Możesz po prostu zrobićregmatches(x, regexpr(".{6}$", x))
thelatemail

10

AKTUALIZACJA : jak zauważył mdsumner , oryginalny kod jest już wektoryzowany, ponieważ substr jest. Powinien być bardziej ostrożny.

A jeśli chcesz wersję wektorową (na podstawie kodu 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"

Zauważ, że zmieniłem (nchar(x)-n)na, (nchar(x)-n+1)aby zdobyć npostacie.


Myślę, że masz na myśli „ (nchar(x)-n)do (nchar(x)-n+1)
Xu Wang

8

Proste podstawowe rozwiązanie R wykorzystujące substring()funkcję (kto wiedział, że ta funkcja w ogóle istniała?):

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

Zaletą tego jest to, że substr()znajduje się on poniżej, ale ma domyślną wartość końcową 1 000 000.

Przykłady:

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

6

Alternatywą substrjest podzielenie łańcucha na listę pojedynczych znaków i przetworzenie, które:

N <- 2
sapply(strsplit(x, ""), function(x, n) paste(tail(x, n), collapse = ""), N)

6
Wyczuwam warzenie bitwy
system.time

4

Ja substrteż używam , ale w inny sposób. Chcę wyodrębnić 6 ostatnich znaków „Daj mi swoje jedzenie”. Oto kroki:

(1) Podziel znaki

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

(2) Wyodrębnij ostatnie 6 znaków

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

Wynik:

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

Dostęp do każdej postaci można uzyskać splits[[1]][x], gdzie x wynosi od 1 do 6.


3

ktoś wcześniej używał podobnego rozwiązania do mojego, ale łatwiej mi myśleć, jak poniżej:

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

Spowoduje to, że ostatnie postacie będą według potrzeb.


3

Spróbuj tego:

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

To powinno dać:

[1] "string"

1

Użyłem następującego kodu, aby uzyskać ostatni znak ciągu.

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

Możesz grać z nchar (stringOfInterest), aby dowiedzieć się, jak zdobyć kilka ostatnich znaków.


0

Mała modyfikacja rozwiązania @Andrie daje również uzupełnienie:

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"

Tego właśnie szukałem. I zaprasza po lewej stronie:

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"

0

Na wszelki wypadek, gdy trzeba wybrać zakres znaków:

# 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"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.