2011-11-01 40 views

Trả lời

191

Tôi không biết bất cứ điều gì trong cơ sở R, nhưng nó thẳng về phía trước để thực hiện một chức năng để làm điều này bằng substrnchar:

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" 

này được vectorised, như điểm @mdsumner ngoài. Xem xét:

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

Và xem ra cho NA ... – hadley

+0

Sử dụng gói stringi. Nó hoạt động tốt với NA và tất cả các mã hóa :) – bartektartanus

+0

Nó sẽ hiệu quả hơn để tránh gọi 'nchar (x)' hai lần bằng cách gán nó vào một biến cục bộ? –

10

CẬP NHẬT: như ghi nhận của mdsumner, mã gốc đã được vectorised vì substr là. Nên cẩn thận hơn.

Và nếu bạn muốn có một phiên bản vectorised (dựa trên mã 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" 

Lưu ý rằng tôi đã thay đổi (nchar(x)-n) để (nchar(x)-n+1) để có được n ký tự.

+0

Tôi nghĩ bạn có nghĩa là "' (nchar (x) -n) 'đến' (nchar (x) -n + 1) '" –

+0

Andrie's đã được vector hóa. – mdsumner

+3

sapply! = Vectorized –

119

Nếu bạn không nhớ bằng cách sử dụng gói stringr, str_sub rất thuận tiện vì bạn có thể sử dụng âm để đếm ngược:

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

Hoặc, như Max chỉ ra trong một chú thích cho câu trả lời này,

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

cũng vậy, str_sub (x, start = -n) lấy n ký tự cuối cùng. – Max

+1

stringr không hoạt động tốt với giá trị của NA và tất cả mã hóa. Tôi mạnh mẽ khuyên bạn nên gói stringi :) – bartektartanus

+2

Tôi tin rằng 'stringr' đã được làm lại bằng cách sử dụng' stringi' như là một phụ trợ, vì vậy nên làm việc với NAs vv bây giờ. –

6

một thay thế cho substr là để phân chia các chuỗi vào một danh sách các nhân vật duy nhất và quá trình đó:

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

Tôi cảm nhận được một hệ thống.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

Đây là câu trả lời tốt nhất mà không liên quan đến việc sử dụng bất kỳ gói nào – prab4th

33

Sử dụng stri_sub chức năng từ gói stringi. Để nhận chuỗi con từ cuối, hãy sử dụng số âm. Xem bên dưới cho các ví dụ:

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

Bạn có thể cài đặt gói này từ github: https://github.com/Rexamine/stringi

Nó có sẵn trên cran bây giờ, chỉ cần gõ

install.packages("stringi") 

để cài đặt gói này.

7

Một cách hợp lý đơn giản là sử dụng biểu thức thông thường và sub:

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

Vì vậy, "thoát khỏi tất cả mọi thứ theo sau là một nhân vật". Để chụp được nhiều ký tự tắt Cuối cùng, thêm tuy nhiên nhiều dấu chấm trong sự khẳng định lookahead:

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

nơi .{2} nghĩa .., hoặc "hai nhân vật bất kỳ", do đó có nghĩa là "thoát khỏi tất cả mọi thứ sau đó là hai nhân vật".

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

cho ba nhân vật, vv Bạn có thể thiết lập số lượng ký tự để lấy với một biến, nhưng bạn sẽ phải paste giá trị biến vào chuỗi biểu thức chính quy:

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

Để tránh tất cả các giao diện, vv, bạn có thể thực hiện 'regmatches (x, regexpr (". {6} $ ", x))' – thelatemail

4

tôi sử dụng substr quá, nhưng theo một cách khác. Tôi muốn trích xuất 6 ký tự cuối cùng của "Hãy cho tôi thức ăn của bạn." Dưới đây là các bước:

(1) Tách các nhân vật

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

(2) Giải nén 6 ký tự cuối cùng

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

Output:

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

Mỗi phòng trong số nhân vật có thể truy cập bằng splits[[1]][x], trong đó x là 1 đến 6.

0

Một thay đổi nhỏ trên giải pháp @Andrie cũng cung cấp cho các bổ sung:

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" 

Đó là những gì tôi đang tìm kiếm. Và nó mời về phía bên trái:

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

ai đó trước khi sử dụng một giải pháp tương tự như tôi, nhưng tôi tìm thấy nó dễ dàng hơn để suy nghĩ như sau:

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

này sẽ mang lại các nhân vật cuối cùng như mong muốn.

1

Tôi đã sử dụng mã sau để lấy ký tự cuối cùng của chuỗi.

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

Bạn có thể chơi với nchar (stringOfInterest) để tìm hiểu cách nhận vài ký tự cuối cùng.

1

Một giải pháp cơ sở R đơn giản bằng cách sử dụng chức năng substring() (ai biết chức năng này thậm chí còn tồn tại?):

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

này có lợi thế về cơ bản là substr() bên dưới nhưng có một giá trị kết thúc mặc định là 1.000.000.

Ví dụ:

> RIGHT('Hello World!',2) 
[1] "d!" 
> RIGHT('Hello World!',8) 
[1] "o World!" 
Các vấn đề liên quan