[R] Adding values to the end of a vector?

Gabor Grothendieck ggrothendieck at myway.com
Tue Jan 4 19:35:26 CET 2005


I thought it would be interesting to actually time this.

1. In the first example we keep appending
the square of an N(0.1) r.v. to v until the total is 20000 or more.

2. In the second example we double v's length each time it needs
to be extended.  Even with only 20,000 elements the doubling
strategy is an order of magnitude faster.  

3. In the third example,
we preallocate 30,000 just to be sure we have enough space.  This 
is only slightly faster than #2 and has the downside that we had to 
decide how much to preallocate in advance.

R> # successively append 
R> set.seed(1); s <- 0; v <- numeric()
R> system.time({
+ while(s<20000) {
+ r <- rnorm(1)
+ v <- append(v, r)
+ s <- s+r*r
+ }
+ }, gc = TRUE)
[1] 10.35  0.03 11.25    NA    NA

R> # double length whenever end is reached
R> set.seed(1); s <- 0; v <- numeric(); vlen <- 0
R> system.time({
+ while(s<20000) {
+ if (vlen == length(v)) length(v) <- 2*length(v)
+ vlen <- vlen+1
+ v[vlen] <- r <- rnorm(1)
+ s <- s+r*r
+ }
+ }, gc = TRUE)
[1] 1.12 0.00 1.21   NA   NA

R> # preallocate some space
R> set.seed(1); s <- 0; v <- numeric(30000); vlen <- 0
R> system.time({
+ while(s<20000) {
+ vlen <- vlen+1
+ v[vlen] <- r <- rnorm(1)
+ s <- s+r*r
+ }
+ }, gc = TRUE)
[1] 0.99 0.00 1.10   NA   NA


Thomas Lumley <tlumley <at> u.washington.edu> writes:

: 
: On Tue, 4 Jan 2005, Daniel Almirall wrote:
: 
: >
: > I am curious.  How are these suggestions different (better, worse?) from
: >
: > x <- NULL
: > for (i in 1:5) x <- c(x, i)
: 
: One imporant difference is between solutions that preallocate storage and 
: those that don't.
:    x<-numeric(5)
:    for(i in 1:5) x[i]<-i
: allocates one vector of length 5 and then modifies it, but
:    x<-NULL
:    for(i in 1:5) x<-c(x,i)
: allocates vectors of length 1, 2, 3, 4, 5 in turn.
: 
: You can't tell this from anything in the language definition, since 
: conceptually x[i]<-i also copies: it does
:     x <- "[<-"(x,i,i)
: and for more complicated replacement functions it will really copy.  Even 
: if the first version really copied there would be some potential for 
: having more efficient memory allocation with all the objects being of size 
: 5 (at least, for very large values of 5).
: 
: If you don't know how long the vector needs to be then you can't 
: preallocate, but a common programming strategy in other languages is to 
: allocate powers of 2 (eg start out with x<-numeric(4) and if that isn't 
: big enough do something like x<-c(x,numeric(4)) to double the size). I 
: don't know if anyone has looked at whether this is ever useful in R.
: 
:  	-thomas
: 
: >
: > Thanks,
: > Danny
: >
: >
: >
: > On Tue, 4 Jan 2005, John Fox wrote:
: >
: >> Dear Dan,
: >>
: >> The following also works:
: >>
: >>> x <- numeric(0)
: >>> for (i in 1:5) x[i] <- i
: >>> x
: >> [1] 1 2 3 4 5
: >>
: >> It's worth noting, however, that extending a vector in this manner can be
: >> very inefficient for large vectors, since the vector is recopied each 
time.
: >> If you can anticipate the number of elements (or place an upper bound on
: >> it), then it's better to do something like
: >>
: >>> x <- numeric(5)
: >>> for (i in 1:5) x[i] <- i
: >>
: >> I hope this helps,
: >>  John
: >>
: >> --------------------------------
: >> John Fox
: >> Department of Sociology
: >> McMaster University
: >> Hamilton, Ontario
: >> Canada L8S 4M4
: >> 905-525-9140x23604
: >> http://socserv.mcmaster.ca/jfox
: >> --------------------------------
: >>
: >>> -----Original Message-----
: >>> From: r-help-bounces <at> stat.math.ethz.ch
: >>> [mailto:r-help-bounces <at> stat.math.ethz.ch] On Behalf Of Liaw, Andy
: >>> Sent: Tuesday, January 04, 2005 8:51 AM
: >>> To: 'Dan Bolser'; R mailing list
: >>> Subject: RE: [R] Adding values to the end of a vector?
: >>>
: >>> Is this what you're looking for?
: >>>
: >>>> x <- numeric(0)
: >>>> for (i in 1:5) x <- append(x, i)
: >>>> x
: >>> [1] 1 2 3 4 5
: >>>
: >>> Andy
: >>>
: >>>
: >>>> From: Dan Bolser
: >>>>
: >>>> I want to add values onto the end of a vector, for example...
: >>>>
: >>>> x <- vector
: >>>>
: >>>> for (i in 1:5){
: >>>>   add_to_end_of_vector(i,x)
: >>>> }
: >>>>
: >>>> I just cant find the answer to this question!
: >>>>
: >>>>
: >>>> Sorry for such a basic question, I tried...
: >>>>
: >>>> x <- c()
: >>>>
: >>>> for (i in 1:5) x[length(x)] <- i
: >>>>
: >>>> but it didn't work.




More information about the R-help mailing list