[R] blockwise sums

Berton Gunter gunter.berton at gene.com
Tue Aug 31 18:39:09 CEST 2004


This is a cute problem, so how about a cute algorithm? Since all that is
wanted is the sum, matrix multiplication can be used. If n=vector length and
b = blocksize, then the issue comes down to constructing a block diagonal
matrix with nblk=n%/%b columns with b 1's in each block to multiply the
first b*nblk elements of the vector by (the sum of any remaining elements
can be appended to the result). This muliplier matrix is easily constructed
using diag():

matrix(rep(diag(nblk),each=b),ncol=nblk)

There may even be slicker ways to do it. Anyway, as no implicit looping
(tapply) is used, I suspect this would run considerably faster,too, although
this may be unimportant, and I haven't tested it.

Of course, this approach doesn't generalize. But it is a nice example of
some of R's little tricks.

Cheers,

-- Bert Gunter
Genentech Non-Clinical Statistics
South San Francisco, CA
 
"The business of the statistician is to catalyze the scientific learning
process."  - George E. P. Box
 
 

> -----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, August 31, 2004 5:42 AM
> To: 'Barry Rowlingson'
> Cc: r-help at stat.math.ethz.ch
> Subject: RE: [R] blockwise sums
> 
> > From: Barry Rowlingson 
> > 
> > Liaw, Andy wrote:
> > > If you insist, here's one way:
> > > 
> > > my.blockwisesum <- function(x, n, ...) {
> > >     tapply(x, seq(1, length(x), by=n), sum, ...)
> > > }
> > > 
> > 
> >   Did you test that? I get:
> 
> Of course not (slap on wrist)!!  My apologies...
> 
> Andy
>  
> >  > my.blockwisesum(1:10, 3)
> > Error in tapply(x, seq(1, length(x), by = n), sum, ...) :
> >          arguments must have same length
> > 
> > 
> >   Here's my solution with tapply and rep() to generate a 
> vector like 
> > c(1,1,1,2,2,2,3,3,3,4):
> > 
> > baz.blockwisesum=
> >   
> > function(v,n){tapply(v,rep(1:(1+length(v)/n),each=n)[1:length(
> > v)],sum)}
> > 
> >  > baz.blockwisesum(1:10,3)
> >   1  2  3  4
> >   6 15 24 10
> > 
> >   - just ignore the 1 to 4 names, they cant hurt you.
> > 
> > Baz
> > 
> >
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! 
> http://www.R-project.org/posting-guide.html
>




More information about the R-help mailing list