que tienen una cadena como:¿Cómo dividir una cadena en subcadenas de una longitud determinada?
"aabbccccdd"
quiero romper esta cadena en un vector de subcadenas de longitud 2:
"aa" "bb" "cc" "cc" "dd"
que tienen una cadena como:¿Cómo dividir una cadena en subcadenas de una longitud determinada?
"aabbccccdd"
quiero romper esta cadena en un vector de subcadenas de longitud 2:
"aa" "bb" "cc" "cc" "dd"
Esta es una manera
substring("aabbccccdd", seq(1, 9, 2), seq(2, 10, 2))
#[1] "aa" "bb" "cc" "cc" "dd"
o más generalmente
text <- "aabbccccdd"
substring(text, seq(1, nchar(text)-1, 2), seq(2, nchar(text), 2))
#[1] "aa" "bb" "cc" "cc" "dd"
Editar: Esto es mucho, mucho más rápido
sst <- strsplit(text, "")[[1]]
out <- paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)])
En primer lugar, se divide la cadena en caracteres. Luego, pega juntos los elementos pares y los elementos impares.
sincronizaciones
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)
})
que da
[1] "aa" "bb" "cc" "cc" "dd"
Uno puede utilizar una matriz para agrupar los personajes:
s2 <- function(x) {
m <- matrix(strsplit(x, '')[[1]], nrow=2)
apply(m, 2, paste, collapse='')
}
s2('aabbccddeeff')
## [1] "aa" "bb" "cc" "dd" "ee" "ff"
Desafortunadamente, TH es pausas para una entrada de longitud de la cadena impar, dando una advertencia:
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]
Más lamentable es que g1
y g2
de @GSee silencio devolver resultados incorrectos para una entrada de longitud de la cadena impar:
g1('abc')
## [1] "ab"
g2('abc')
## [1] "ab" "cb"
Aquí está la función en el espíritu de s2, tomando un parámetro para el número de caracteres en cada grupo, y deja la última entrada corta si es necesario:
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"
(De hecho, es más lento que g2
, pero más rápido que g1
por un factor de aproximadamente 7)
Si es posible tener un número impar de caracteres, entonces me parece que sería más rápido manejar eso después del hecho que para introducir un bucle 'apply'. Apuesto a que es más rápido: 'out <- g2 (x); if (nchar (x) %% 2 == 1L) fuera [length (out)] <- substring (out [length (out)], 1, 1); fuera' – GSee
feo, pero funciona
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")
Da ATG AAT AAA G
hay dos posibilidades fáciles:
s <- "aabbccccdd"
gregexpr
y 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"
interesante, no sabía nada de 'substring'. Mucho más agradable ya que 'substr' no toma args vectoriales para inicio/finalización. –
¡genial! la segunda versión es realmente muy rápida! – MadSeb
Me preguntaba si había algo como esto que dividiría "aabbbcccccdd" en aa bbb ccccc dd Uso grepexpr por el momento. – jackStinger