2011-10-11 51 views
67

Tôi muốn thực hiện một số bước đi 2 chiều bằng chuỗi ký tự bằng cách gán các giá trị khác nhau cho mỗi ký tự. Tôi đã có kế hoạch 'pop' ký tự đầu tiên của một chuỗi, sử dụng nó, và lặp lại cho phần còn lại của chuỗi.Lấy và xóa ký tự đầu tiên của chuỗi

Làm cách nào để tôi có thể đạt được điều gì đó như thế này?

x <- 'hello stackoverflow' 

Tôi muốn để có thể làm điều gì đó như thế này:

a <- x.pop[1] 

print(a) 

'h' 
print(x) 

'ello stackoverflow' 

Trả lời

109

Xem ?substring.

x <- 'hello stackoverflow' 
substring(x, 1, 1) 
## [1] "h" 
substring(x, 2) 
## [1] "ello stackoverflow" 

Ý tưởng của việc có một phương pháp pop rằng cả hai trả về giá trị và có một tác dụng phụ của việc cập nhật các dữ liệu lưu trữ trong x là rất nhiều một khái niệm từ lập trình hướng đối tượng. Vì vậy, thay vì xác định hàm pop để hoạt động trên các vectơ ký tự, chúng ta có thể tạo một reference class với phương thức pop.

PopStringFactory <- setRefClass(
    "PopString", 
    fields = list(
    x = "character" 
), 
    methods = list(
    initialize = function(x) 
    { 
     x <<- x 
    }, 
    pop = function(n = 1) 
    { 
     if(nchar(x) == 0) 
     { 
     warning("Nothing to pop.") 
     return("") 
     } 
     first <- substring(x, 1, n) 
     x <<- substring(x, n + 1) 
     first 
    } 
) 
) 

x <- PopStringFactory$new("hello stackoverflow") 
x 
## Reference class object of class "PopString" 
## Field "x": 
## [1] "hello stackoverflow" 
replicate(nchar(x$x), x$pop()) 
## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w" 
8

Sử dụng chức năng này từ stringi gói

> x <- 'hello stackoverflow' 
> stri_sub(x,2) 
[1] "ello stackoverflow" 
3

xoá các ký tự đầu tiên:

x <- 'hello stackoverflow' 
substring(x, 2, nchar(x)) 

Idea là chọn tất cả các ký tự bắt đầu từ 2 đến số ký tự trong x. Điều này rất quan trọng khi bạn có số ký tự không bằng nhau trong từ hoặc cụm từ.

Lựa chọn chữ cái đầu tiên là tầm thường như câu trả lời trước:

substring(x,1,1) 
6

substring chắc chắn là tốt nhất, nhưng đây là một strsplit thay thế, kể từ khi tôi chưa thấy một được nêu ra.

> x <- 'hello stackoverflow' 
> strsplit(x, '')[[1]][1] 
## [1] "h" 

hoặc tương đương

> unlist(strsplit(x, ''))[1] 
## [1] "h" 

Và bạn có thể paste phần còn lại của chuỗi lại với nhau.

> paste0(strsplit(x, '')[[1]][-1], collapse = '') 
## [1] "ello stackoverflow" 
4

Cũng str_sub là từ gói stringr

x <- 'hello stackoverflow' 
str_sub(x, 2) # or 
str_sub(x, 2, str_length(x)) 
[1] "ello stackoverflow" 
1

Một lựa chọn khác là sử dụng chụp tiểu biểu với các chức năng biểu hiện thường xuyên regmatchesregexec.

# the original example 
x <- 'hello stackoverflow' 

# grab the substrings 
myStrings <- regmatches(x, regexec('(^.)(.*)', x)) 

này trả về toàn bộ chuỗi, ký tự đầu tiên, và "popped" kết quả trong một danh sách dài 1.

myStrings 
[[1]] 
[1] "hello stackoverflow" "h"     "ello stackoverflow" 

tương đương với list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))).Nghĩa là, nó chứa tập hợp siêu các phần tử mong muốn cũng như chuỗi đầy đủ.


Thêm sapply sẽ cho phép phương pháp này để làm việc cho một vector đặc trưng của length> 1.

# a slightly more interesting example 
xx <- c('hello stackoverflow', 'right back', 'at yah') 

# grab the substrings 
myStrings <- regmatches(x, regexec('(^.)(.*)', xx)) 

này trả về một danh sách với chuỗi đầy đủ phù hợp là yếu tố đầu tiên và subexpressions khớp bắt bởi () như các yếu tố sau. Vì vậy, trong biểu thức chính quy '(^.)(.*)', (^.) khớp với ký tự đầu tiên và (.*) khớp với các ký tự còn lại.

myStrings 
[[1]] 
[1] "hello stackoverflow" "h"     "ello stackoverflow" 

[[2]] 
[1] "right back" "r"   "ight back" 

[[3]] 
[1] "at yah" "a"  "t yah" 

Bây giờ, chúng ta có thể sử dụng các phương pháp đáng tin cậy sapply + [ phải rút ra khỏi các chuỗi con mong muốn.

myFirstStrings <- sapply(myStrings, "[", 2) 
myFirstStrings 
[1] "h" "r" "a" 
mySecondStrings <- sapply(myStrings, "[", 3) 
mySecondStrings 
[1] "ello stackoverflow" "ight back"   "t yah" 
+0

Đây là một mẹo rất hay nhưng tôi nghĩ rằng bỏ lỡ câu hỏi. – pedrosaurio

+0

Bạn sẽ cần phải giải thích thêm vì nó có thể tạo ra cùng một đầu ra như các câu trả lời khác. Xem khối mã cuối cùng sử dụng 'sapply' để trích xuất. "popping" ký tự đầu tiên, như được chỉ định trong câu hỏi, là vấn đề lặp lại quá trình này trên vectơ kết quả (mySecondStrings). – lmo

+0

Chắc chắn nó hoạt động với lời giải thích thêm bạn vừa thêm nhưng tôi vẫn thấy nó phức tạp hơn nó nên. – pedrosaurio

Các vấn đề liên quan