Ich habe eine Zeichenfolge wie:Wie teilt man einen String in Teilstrings einer bestimmten Länge auf?
"aabbccccdd"
ich diese Zeichenfolge in einen Vektor von Teillängen brechen wollen 2:
"aa" "bb" "cc" "cc" "dd"
Ich habe eine Zeichenfolge wie:Wie teilt man einen String in Teilstrings einer bestimmten Länge auf?
"aabbccccdd"
ich diese Zeichenfolge in einen Vektor von Teillängen brechen wollen 2:
"aa" "bb" "cc" "cc" "dd"
Hier ist ein Weg,
substring("aabbccccdd", seq(1, 9, 2), seq(2, 10, 2))
#[1] "aa" "bb" "cc" "cc" "dd"
oder allgemeiner
text <- "aabbccccdd"
substring(text, seq(1, nchar(text)-1, 2), seq(2, nchar(text), 2))
#[1] "aa" "bb" "cc" "cc" "dd"
Edit: Das ist viel, viel schneller
sst <- strsplit(text, "")[[1]]
out <- paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)])
Es zuerst die Zeichenfolge in Zeichen aufteilt. Dann fügt es die geraden Elemente und die ungeraden Elemente zusammen.
Timings
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)
})
Welche
[1] "aa" "bb" "cc" "cc" "dd"
Man gibt die Zeichen eine Matrix Gruppe verwenden können:
s2 <- function(x) {
m <- matrix(strsplit(x, '')[[1]], nrow=2)
apply(m, 2, paste, collapse='')
}
s2('aabbccddeeff')
## [1] "aa" "bb" "cc" "dd" "ee" "ff"
Leider th ist Pause für eine Eingabe von ungeraden String-Länge, eine Warnung zu geben: unglückliche
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]
Mehr ist, dass g1
und g2
von @GSee leise falschen Ergebnissen für eine Eingabe von ungeraden String-Länge zurück:
g1('abc')
## [1] "ab"
g2('abc')
## [1] "ab" "cb"
Hier ist eine Funktion im Geist von s2, die einen Parameter für die Anzahl von Zeichen in jeder Gruppe nimmt und den letzten Eintrag bei Bedarf kurz lässt:
(Es ist in der Tat langsamer als g2
, aber schneller als g1
um etwa den Faktor 7)
Wenn es möglich ist, eine ungerade Anzahl von Zeichen zu haben, dann scheint es mir schneller nach der Tatsache als das zu handhaben um eine 'Apply'-Schleife einzuführen. Ich wette, das ist schneller: 'out <- g2 (x); if (nchar (x) %% 2 == 1L) out [Länge (out)] <- Teilstring (out [Länge (out)], 1, 1); aus' – GSee
hässlich, aber arbeitet
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")
ATG AAT AAA G
es zwei gibt, sind einfache Möglichkeiten:
s <- "aabbccccdd"
gregexpr
und 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"
Interessante, wusste nicht, über 'substring'. Viel schöner, da 'substr' keine Vektorargumente für Start/Ende benötigt. –
brilliant! Die zweite Version ist wirklich sehr schnell! – MadSeb
Ich fragte mich, ob es so etwas gäbe, das "aabbbcccccdd" in ein bbb ccccc dd zerlegen würde. Ich benutze greexp im Moment. – jackStinger