2012-07-23 7 views

Antwort

38

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 
+0

Interessante, wusste nicht, über 'substring'. Viel schöner, da 'substr' keine Vektorargumente für Start/Ende benötigt. –

+2

brilliant! Die zweite Version ist wirklich sehr schnell! – MadSeb

+0

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

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) 
}) 

Welche

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

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)

+0

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

1

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

5

es zwei gibt, sind einfache Möglichkeiten:

s <- "aabbccccdd" 
  1. gregexpr und regmatches:

    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" 
    
Verwandte Themen