Skip to content

Successive subsets from a vector?

7 messages · kone, jim holtman, Brian Ripley +3 more

#
embed(VECTOR, 5)[, 5:1]

gives the subsets, so something like

    apply(embed(VECTOR, 5)[, 5:1], 1, paste, collapse="")

does the job.

The following is a bit more efficient

    ind <- 1:(length(VECTOR)-4)
    do.call(paste, c(lapply(0:4, function(j) VECTOR[ind+j]), sep=""))

but by looking at how embed() works it could be made as efficient.

Larger example:

VECTOR <- sample(1:10, 1e5, replace=TRUE)
[1] 5.73 0.05 5.81   NA   NA
+ do.call(paste, c(lapply(0:4, function(j) VECTOR[ind+j]), sep=""))
+ })
[1] 1.00 0.01 1.01   NA   NA

The loop method took 195 secs.  Just assigning to an answer of the correct 
length reduced this to 5 secs.  e.g. use

    ADDRESSES <- character(length(VECTOR)-4)

Moral: don't grow vectors repeatedly.
On Tue, 22 Aug 2006, kone wrote:

            
You do not need the semicolons, and they just confuse readers.

  
    
#
Thanks!

I have used tons of for- and while-loops (I'm ashamed to reveal these scripts, but I'm primarily a musician;-) http://users.utu.fi/attenka/SetTheoryScripts.r), taken some or more cup of cocoa and mostly been happy ;-) Now I got so many new ways to do these things, that it takes a while to ruminate all the ideas here.

Atte
#
Other languages (eg. Java) grow the size of the vector independently
of the number of observations in it (I think Java doubles the size
whenever the vector is filled), thus changing O(n) behaviour to O(log
n).  I've always wondered why R doesn't do this.

Hadley
#
On Tue, 22 Aug 2006, hadley wickham wrote:

            
At one point at least that was too expensive on memory/address space (and 
it may still be for 32-bit OSes). There is even a 'truelength' field in 
the vector header to allow for such a strategy, and the strategy is used 
in scan() and elsewhere.

In my experience it is relatively rare not to know the vector length in 
advance in R code.
#
Here is a solution that uses gsub with a negative lookahead perl-style
regexp to do it:

VECTOR <- c(1,4,2,6,5,0,11,10,4,3,6,8,6)
e <- "([[:digit:]]+),(?=([[:digit:]]+),([[:digit:]]+),([[:digit:]]+),([[:digit:]]+))"
out <- gsub(e, "\\1\\2\\3\\4\\5 ", paste(VECTOR, collapse = ","), perl = TRUE)
head(strsplit(out, " ")[[1]], -1)  # uses head from R 2.4.0
On 8/22/06, kone <attenka at utu.fi> wrote: