2012-07-23 42 views

Trả lời

38

Dưới đây là một cách

substring("aabbccccdd", seq(1, 9, 2), seq(2, 10, 2)) 
#[1] "aa" "bb" "cc" "cc" "dd" 

hoặc thông thường hơn

text <- "aabbccccdd" 
substring(text, seq(1, nchar(text)-1, 2), seq(2, nchar(text), 2)) 
#[1] "aa" "bb" "cc" "cc" "dd" 

Chỉnh sửa: Đây là nhiều, nhanh hơn nhiều

sst <- strsplit(text, "")[[1]] 
out <- paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)]) 

Nó đầu tiên chia tách chuỗi thành ký tự. Sau đó, nó dán với nhau các yếu tố thậm chí và các yếu tố kỳ lạ.

Thời gian

text <- paste(rep(paste0(letters, letters), 1000), collapse="") 
g1 <- function(text) { 
    substring(text, seq(1, nchar(text)-1, 2), seq(2, nchar(text), 2)) 
} 
g2 <- function(text) { 
    sst <- strsplit(text, "")[[1]] 
    paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)]) 
} 
identical(g1(text), g2(text)) 
#[1] TRUE 
library(rbenchmark) 
benchmark(g1=g1(text), g2=g2(text)) 
# test replications elapsed relative user.self sys.self user.child sys.child 
#1 g1   100 95.451 79.87531 95.438  0   0   0 
#2 g2   100 1.195 1.00000  1.196  0   0   0 
+0

Thú vị, không biết về 'substring'. Đẹp hơn nhiều vì 'substr' không lấy tham số vectơ cho đầu/cuối. –

+2

rực rỡ! phiên bản thứ hai thực sự rất nhanh! – MadSeb

+0

Tôi đã tự hỏi nếu có một cái gì đó như thế này mà sẽ chia "aabbbcccccdd" thành aa bbb ccccc dd Tôi sử dụng grepexpr vào lúc này. – jackStinger

8
string <- "aabbccccdd" 
# total length of string 
num.chars <- nchar(string) 

# the indices where each substr will start 
starts <- seq(1,num.chars, by=2) 

# chop it up 
sapply(starts, function(ii) { 
    substr(string, ii, ii+1) 
}) 

Mà cho

[1] "aa" "bb" "cc" "cc" "dd" 
1

Người ta có thể sử dụng một ma trận để nhóm các nhân vật:

s2 <- function(x) { 
    m <- matrix(strsplit(x, '')[[1]], nrow=2) 
    apply(m, 2, paste, collapse='') 
} 

s2('aabbccddeeff') 
## [1] "aa" "bb" "cc" "dd" "ee" "ff" 

Thật không may, thứ là phá vỡ cho một đầu vào có độ dài chuỗi lẻ, đưa ra một cảnh báo:

s2('abc') 
## [1] "ab" "ca" 
## Warning message: 
## In matrix(strsplit(x, "")[[1]], nrow = 2) : 
## data length [3] is not a sub-multiple or multiple of the number of rows [2] 

bất hạnh hơn là g1g2 từ @GSee âm thầm trả lại kết quả không chính xác cho một đầu vào có độ dài chuỗi lẻ:

g1('abc') 
## [1] "ab" 

g2('abc') 
## [1] "ab" "cb" 

đây là chức năng theo tinh thần của s2, lấy một tham số cho số ký tự trong mỗi nhóm, và lá mục cuối cùng ngắn nếu cần thiết:

s <- function(x, n) { 
    sst <- strsplit(x, '')[[1]] 
    m <- matrix('', nrow=n, ncol=(length(sst)+n-1)%/%n) 
    m[seq_along(sst)] <- sst 
    apply(m, 2, paste, collapse='') 
} 

s('hello world', 2) 
## [1] "he" "ll" "o " "wo" "rl" "d" 
s('hello world', 3) 
## [1] "hel" "lo " "wor" "ld" 

(Nó thực sự là chậm hơn so với g2, nhưng nhanh hơn so với g1 khoảng một yếu tố của 7)

+0

Nếu có thể có một số ký tự lẻ, thì có vẻ như tôi sẽ xử lý nhanh hơn sau sự kiện để giới thiệu một vòng lặp 'áp dụng'. Tôi cá là nhanh hơn: 'out <- g2 (x); if (nchar (x) %% 2 == 1L) ra [length (out)] <- substring (out [length (out)], 1, 1); out' – GSee

1

Ugly nhưng việc

sequenceString <- "ATGAATAAAG" 

J=3#maximum sequence length in file 
sequenceSmallVecStart <- 
    substring(sequenceString, seq(1, nchar(sequenceString)-J+1, J), 
    seq(J,nchar(sequenceString), J)) 
sequenceSmallVecEnd <- 
    substring(sequenceString, max(seq(J, nchar(sequenceString), J))+1) 
sequenceSmallVec <- 
    c(sequenceSmallVecStart,sequenceSmallVecEnd) 
cat(sequenceSmallVec,sep = "\n") 

Cho ATG AAT AAA G

5

Có hai khả năng dễ dàng:

s <- "aabbccccdd" 
  1. gregexprregmatches:

    regmatches(s, gregexpr(".{2}", s))[[1]] 
    # [1] "aa" "bb" "cc" "cc" "dd" 
    
  2. strsplit:

    strsplit(s, "(?<=.{2})", perl = TRUE)[[1]] 
    # [1] "aa" "bb" "cc" "cc" "dd" 
    
Các vấn đề liên quan