Tôi có một chuỗi như:Làm thế nào để tách một chuỗi thành các chuỗi có chiều dài nhất định?
"aabbccccdd"
Tôi muốn phá vỡ chuỗi này thành một vector của chuỗi con có độ dài 2:
"aa" "bb" "cc" "cc" "dd"
Tôi có một chuỗi như:Làm thế nào để tách một chuỗi thành các chuỗi có chiều dài nhất định?
"aabbccccdd"
Tôi muốn phá vỡ chuỗi này thành một vector của chuỗi con có độ dài 2:
"aa" "bb" "cc" "cc" "dd"
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
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"
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à g1
và g2
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)
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
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
Có hai khả năng dễ dàng:
s <- "aabbccccdd"
gregexpr
và regmatches
:
regmatches(s, gregexpr(".{2}", s))[[1]]
# [1] "aa" "bb" "cc" "cc" "dd"
strsplit
:
strsplit(s, "(?<=.{2})", perl = TRUE)[[1]]
# [1] "aa" "bb" "cc" "cc" "dd"
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. –
rực rỡ! phiên bản thứ hai thực sự rất nhanh! – MadSeb
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