Extrahieren der letzten n Zeichen aus einer Zeichenfolge in R.


271

Wie kann ich die letzten n Zeichen aus einer Zeichenfolge in R abrufen? Gibt es eine Funktion wie SQL RIGHT?

Antworten:


280

Mir ist nichts in Basis R bekannt, aber es ist einfach, eine Funktion zu erstellen, um dies mit substrund zu tun 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"

Dies ist vektorisiert, wie @mdsumner betont. Erwägen:

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

1
Verwenden Sie das Stringi-Paket. Es funktioniert gut mit NAs und allen Codierungen :)
Bartektartanus

Wäre es effizienter, einen nchar(x)doppelten Aufruf zu vermeiden, indem Sie ihn einer lokalen Variablen zuweisen?
Dave Jarvis

206

Wenn es Ihnen nichts ausmacht, das stringrPaket zu verwenden, str_subist dies praktisch, da Sie Negative verwenden können, um rückwärts zu zählen:

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

Oder, wie Max in einem Kommentar zu dieser Antwort betont,

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

32
Außerdem erhält str_sub (x, start = -n) n letzte Zeichen.
Max

2
stringr funktioniert nicht gut mit dem Wert von NA und der gesamten Codierung. Ich kann das Stringi-Paket nur empfehlen :)
Bartektartanus

3
Ich glaube, stringres wurde stringials Backend neu erstellt, sollte also jetzt mit NAs usw. funktionieren.
m-dz

44

Verwenden Sie die stri_subFunktion aus dem stringiPaket. Verwenden Sie negative Zahlen, um die Teilzeichenfolge vom Ende zu erhalten. Schauen Sie sich unten die Beispiele an:

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

Sie können dieses Paket von github installieren: https://github.com/Rexamine/stringi

Es ist jetzt auf CRAN verfügbar. Geben Sie einfach ein

install.packages("stringi")

um dieses Paket zu installieren.


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

> [1] "example"
> 

12

Eine andere ziemlich einfache Möglichkeit ist die Verwendung regulärer Ausdrücke und sub:

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

Also, "alles loswerden, gefolgt von einem Charakter". Fügen Sie der Lookahead-Behauptung jedoch so viele Punkte hinzu, um am Ende mehr Zeichen zu erhalten:

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

wo .{2}bedeutet .., oder "zwei beliebige Zeichen", was bedeutet "alles loswerden, gefolgt von zwei Zeichen".

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

für drei Zeichen usw. Sie können die Anzahl der Zeichen festlegen, die mit einer Variablen erfasst werden sollen, aber Sie müssen pasteden Variablenwert in die Zeichenfolge für reguläre Ausdrücke eingeben:

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

2
Um alle Vorausschau usw. zu vermeiden, könnten Sie einfach tunregmatches(x, regexpr(".{6}$", x))
E-Mail

10

UPDATE : Wie von mdsumner festgestellt , ist der ursprüngliche Code bereits vektorisiert, da substr ist. Hätte vorsichtiger sein sollen.

Und wenn Sie eine vektorisierte Version möchten (basierend auf Andries Code)

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"

Beachten Sie, dass ich geändert (nchar(x)-n)habe (nchar(x)-n+1), um nZeichen zu erhalten .


Ich denke du meinst " (nchar(x)-n)zu (nchar(x)-n+1)"
Xu Wang

8

Eine einfache Basis-R-Lösung mit der substring()Funktion (wer wusste, dass diese Funktion überhaupt existiert?):

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

Dies nutzt den Vorteil, im Grunde genommen substr()darunter zu sein, hat aber einen Standardendwert von 1.000.000.

Beispiele:

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

6

Eine Alternative dazu substrbesteht darin, die Zeichenfolge in eine Liste einzelner Zeichen aufzuteilen und Folgendes zu verarbeiten:

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

6
Ich spüre ein system.time () Battle Brewing :-)
Carl Witthoft

4

Ich benutze substrauch, aber auf eine andere Art und Weise. Ich möchte die letzten 6 Zeichen von "Gib mir dein Essen" extrahieren. Hier sind die Schritte:

(1) Teilen Sie die Zeichen

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

(2) Extrahieren Sie die letzten 6 Zeichen

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

Ausgabe:

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

Auf jedes der Zeichen kann zugegriffen werden splits[[1]][x], wobei x 1 bis 6 ist.


3

Jemand zuvor verwendet eine ähnliche Lösung wie ich, aber ich finde es einfacher, wie folgt zu denken:

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

Dadurch werden die letzten Zeichen wie gewünscht angezeigt.


3

Versuche dies:

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

Es sollte geben:

[1] "string"

1

Ich habe den folgenden Code verwendet, um das letzte Zeichen einer Zeichenfolge abzurufen.

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

Sie können mit dem nchar (stringOfInterest) spielen, um herauszufinden, wie Sie die letzten Zeichen erhalten.


0

Eine kleine Modifikation der @ Andrea-Lösung bietet auch die Ergänzung:

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"

Das war es, wonach ich gesucht habe. Und es lädt zur linken Seite ein:

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

Nur für den Fall, dass eine Reihe von Zeichen ausgewählt werden müssen:

# 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"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.