2011-11-01 8 views

risposta

191

Io non sono a conoscenza di nulla nella base di R, ma è straight-forward per fare una funzione per fare questo usando substr e 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" 

Questo è Vectorised, come punti @mdsumner su. Si consideri:

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

e guardare fuori per AN ... – hadley

+0

usare il pacchetto stringi. Funziona bene con NA e tutte le codifiche :) – bartektartanus

+0

Sarebbe più efficiente evitare di chiamare 'nchar (x)' due volte assegnandolo a una variabile locale? –

10

UPDATE: come ha osservato mdsumner, il codice originale è già Vectorised perché substr è. Dovrebbe essere stato più attento.

E se volete una versione Vectorised (basato sul codice Andrie s')

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" 

Nota che ho cambiato (nchar(x)-n) per (nchar(x)-n+1) per ottenere n caratteri.

+0

Penso che intendiate "' (nchar (x) -n) 'a' (nchar (x) -n + 1) '" –

+0

Andrie è già vettorizzato. – mdsumner

+3

sapply! = Vectorized –

119

Se non ti dispiace utilizzando il pacchetto stringr, str_sub è utile perché si può usare negativi per contare a ritroso:

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

Oppure, come sottolinea Max in un commento a questa risposta,

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

inoltre, str_sub (x, start = -n) ottiene gli ultimi n caratteri. – Max

+1

stringr non funziona bene con il valore di NA e tutte le codifiche. Raccomando caldamente il pacchetto stringi :) – bartektartanus

+2

Credo che 'stringr' sia stato rifatto usando' stringai' come backend, quindi ora dovremmo lavorare con NAs ecc. –

6

un'alternativa a substr è quello di dividere la stringa in una lista di personaggi singoli e processo che:

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

Sento un sistema.time() battle brewing :-) –

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

> [1] "example" 
> 
+0

Questa è la migliore risposta che non prevede l'uso di alcun pacchetto – prab4th

33

Utilizzare la funzione stri_sub dal pacchetto stringi. Per ottenere la sottostringa dalla fine, utilizzare numeri negativi. Guardate di seguito per gli esempi:

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

È possibile installare questo pacchetto da github: https://github.com/Rexamine/stringi

E 'disponibile sul CRAN ora, è sufficiente digitare

install.packages("stringi") 

per installare questo pacchetto.

7

Un altro modo abbastanza semplice è quello di utilizzare le espressioni regolari e sub:

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

Quindi, "sbarazzarsi di tutto seguito da un carattere". Per afferrare più caratteri al largo alla fine, aggiungere comunque molti punti nella asserzione che guarda avanti:

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

dove .{2} significa .., o "qualsiasi due caratteri", in modo che significa "sbarazzarsi di tutto seguito da due caratteri".

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

per tre personaggi, ecc È possibile impostare il numero di caratteri per afferrare con una variabile, ma dovrete paste il valore della variabile nella stringa di espressione regolare:

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

Per evitare tutti i look-ahead, ecc, si potrebbe fare semplicemente 'regmatches (x, regexpr (". {6} $ ", x))' – thelatemail

4

I usa anche substr, ma in un modo diverso. Voglio estrarre gli ultimi 6 caratteri di "Dammi il tuo cibo". Ecco i passaggi:

(1) dividere i personaggi

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

(2) Estrarre gli ultimi 6 caratteri

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

uscita:

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

Ogni del carattere è accessibile da splits[[1]][x], dove x è da 1 a 6.

0

una piccola modifica sulla soluzione @Andrie dà anche il 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" 

che era quello che stavo cercando. E invita a sinistra:

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" 
2

qualcuno usa prima di una soluzione simile alla mia, ma trovo più facile pensare, come di seguito:

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

questo porterà gli ultimi caratteri, se lo desideri.

1

Ho utilizzato il seguente codice per ottenere l'ultimo carattere di una stringa.

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

Si può giocare con il nchar (stringOfInterest) per capire come ottenere ultimi caratteri.

1

Una soluzione semplice base di R usando la funzione substring() (che conosceva questa funzione anche esistesse?):

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

Questa sfrutta fondamentalmente essere substr() sotto, ma ha un valore finale di default di 1.000.000.

Esempi:

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