2016-08-02 21 views
3

Ich bin auf der Suche nach einer Funktion in R, die eine ganze Zahl geben wird mir erlauben, ein Wort in diese Längenkombination zu teilen, aber mit einem rollenden Effekt.Ein Wort in Längenkombination teilen

Zum Beispiel function("stackoverflow", 4) machen würde:

c("stac", "tack", "acko", "ckov", "kove", "over", "verf", "rflo", "flow") 

Haben Sie Jungs wissen, ob diese Funktion vorhanden ist oder muss ich es schaffen?

Antwort

5
## install.packages("zoo") 

x <- unlist(strsplit("stackoverflow","")) 
zoo::rollapply(x,width=4,FUN = paste0,collapse="") 
# [1] "stac" "tack" "acko" "ckov" "kove" "over" "verf" "erfl" "rflo" "flow" 

Eine Funktion?

foo <- function(input, h) { 
    x <- unlist(strsplit(input,"")) 
    zoo::rollapply(x,width=h,FUN = paste0,collapse="") 
    } 

foo("stackoverflow", 4) 
# [1] "stac" "tack" "acko" "ckov" "kove" "over" "verf" "erfl" "rflo" "flow" 

Ein Benchmark

die Basis R Ansatz Betrachten mit substring():

foo1 <- function(input, h) substring(input, seq_len(nchar(input)-h+1),h:nchar(input)) 

Lassen Sie sich ein sehr lange Spielzeug Zeichenfolge erzeugen:

x <- paste0(rep("a",100000), collapse="") 

system.time(foo(x,4)) 
# user system elapsed 
# 2.280 0.004 2.288 

system.time(foo1(x,4)) 
# user system elapsed 
# 10.492 0.000 10.509 

Also, die scheinbar vektorisierte Funktion substring() ist nicht effizient überhaupt, was eine interessante Beobachtung ist!

+0

Nizza Antwort und +1 verwenden. In der Tat ist rolllappy für sehr lange Strings schneller, aber für 'normale' Strings ist die Base R Version viel schneller (zB probiere 'microbenchmark (foo (" stackoverflow ", 4), foo1 (" stackoverflow ", 4))'). Nicht als Kritik gedacht, sondern nur der Vollständigkeit halber. Bei langen Strings ist es schneller, den Basis-R-Weg zu verwenden, aber mit 'stringi :: stri_sub' anstelle von' substring'. – konvas

+0

Schöne Weise herum danke. Ich wollte keine for-Schleife verwenden, also ist deine Methode viel schneller – zemir

4

Wir können es tun, indem base R

substring(s,seq_len(nchar(s)-4+1),4:nchar(s)) 

Daten

s <- "stackoverflow"