In Mathematica there is a neat feature, where you can change the head of a list from "list" to say "+" and obtain a sum of the list elements. I can't find a way to sum a list of vectors of same length or list of matrices of the same dimension and was curious if something like that exists in R. do.call("+",list) doesn't work because "+" accepts only two arguments, I can obviously use loops but this is quite slow and inelegant. Thanks, Tsvetan
Hi Tsvetan, "Stoyanov, Tsvetan" wrote:> > In Mathematica there is a neat feature, where you can change the head of a list from "list" to say "+" and obtain a sum of the list elements. > I can't find a way to sum a list of vectors of same length or list of matrices of the same dimension and was curious if something like that exists in R. do.call("+",list) doesn't work because "+" accepts only two arguments, I can obviously use loops but this is quite slow and inelegant. >If you are sure all the elements have equal dimension, you can try the following:> x=list(a=1:10,b=11:20,c=21:30) > x$a [1] 1 2 3 4 5 6 7 8 9 10 $b [1] 11 12 13 14 15 16 17 18 19 20 $c [1] 21 22 23 24 25 26 27 28 29 30> rowSums(as.data.frame(x))1 2 3 4 5 6 7 8 9 10 33 36 39 42 45 48 51 54 57 60> y=list(a=matrix(1:10,2,5),+ b=matrix(11:20,2,5), + c=matrix(21:30,2,5))> y$a [,1] [,2] [,3] [,4] [,5] [1,] 1 3 5 7 9 [2,] 2 4 6 8 10 $b [,1] [,2] [,3] [,4] [,5] [1,] 11 13 15 17 19 [2,] 12 14 16 18 20 $c [,1] [,2] [,3] [,4] [,5] [1,] 21 23 25 27 29 [2,] 22 24 26 28 30> matrix(rowSums(as.data.frame(x)),nrow(y[[1]]),ncol(y[[2]]))[,1] [,2] [,3] [,4] [,5] [1,] 33 39 45 51 57 [2,] 36 42 48 54 60>Perhaps there's a better way? Sundar -- Sundar Dorai-Raj PDF Solutions, Inc. Dallas TX
"Stoyanov, Tsvetan" <tsvetan.stoyanov at mirant.com> writes:> In Mathematica there is a neat feature, where you can change the > head of a list from "list" to say "+" and obtain a sum of the list > elements. I can't find a way to sum a list of vectors of same length > or list of matrices of the same dimension and was curious if > something like that exists in R. do.call("+",list) doesn't work > because "+" accepts only two arguments, I can obviously use loops > but this is quite slow and inelegant.psum <- function(...)apply(cbind(...),1,sum) psum(1:3,4:6,1:9) -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Tsvetan Sotyanov asks:> -----Original Message----- > From: Stoyanov, Tsvetan [mailto:tsvetan.stoyanov at mirant.com] > Sent: Friday, December 13, 2002 8:46 AM > To: 'r-help at stat.math.ethz.ch' > Subject: [R] sum a list of vectors > > In Mathematica there is a neat feature, where you can change the head of a > list from "list" to say "+" and obtain a sum of the list elements. > I can't find a way to sum a list of vectors of same length or list of > matrices of the same dimension and was curious if something like that > exists in R. do.call("+",list) doesn't work because "+" accepts only two > arguments, I can obviously use loops but this is quite slow and inelegant.[WNV] Actually, a loop is not all that bad (contrary to the popular prejudice), and the inelegance can be overcome simply by having the right function available. How about "psum" for "parallel sum", like pmax and pmin? psum <- function(...) { x <- list(...) s <- x[[1]] for(j in seq(along=x)) s <- s+x[[j]] s } l <- list(a=1:3, b=2:4, c=3:5) > do.call("psum", l) [1] 7 11 15 As a homework exercise you could fix psum so that it works with a null list of arguments. Use the "most elegant" way you can think of... The solution presented elsewhere using rowSums is probably the best, though, if you can be sure that you are only dealing with vectors and they all have the same length. The advantage of going about it the way outlined above is that the recycling rule kicks in if you need it, or if you are dealing with more general arrays the answer has the right shape. Bill Venables.> Thanks, > Tsvetan > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > http://www.stat.math.ethz.ch/mailman/listinfo/r-help
Thanks for the response. Still, my point is that there isn't a straightforward way to do an operation which should be bread and butter for a language, that prides itself in its connection to Lisp. Tsvetan Stoyanov --------------- From: Bill.Venables at CMIS.CSIRO.AU To: tsvetan.stoyanov at mirant.com, r-help at stat.math.ethz.ch Subject: RE: [R] sum a list of vectors Date: Fri, 13 Dec 2002 09:38:45 +1000 Tsvetan Sotyanov asks:> -----Original Message----- > From: Stoyanov, Tsvetan [mailto:tsvetan.stoyanov at mirant.com] > Sent: Friday, December 13, 2002 8:46 AM > To: 'r-help at stat.math.ethz.ch' > Subject: [R] sum a list of vectors > > In Mathematica there is a neat feature, where you can change the head of a > list from "list" to say "+" and obtain a sum of the list elements. > I can't find a way to sum a list of vectors of same length or list of > matrices of the same dimension and was curious if something like that > exists in R. do.call("+",list) doesn't work because "+" accepts only two > arguments, I can obviously use loops but this is quite slow and inelegant.[WNV] Actually, a loop is not all that bad (contrary to the popular prejudice), and the inelegance can be overcome simply by having the right function available. How about "psum" for "parallel sum", like pmax and pmin? psum <- function(...) { x <- list(...) s <- x[[1]] for(j in seq(along=x)) s <- s+x[[j]] s } l <- list(a=1:3, b=2:4, c=3:5) > do.call("psum", l) [1] 7 11 15 As a homework exercise you could fix psum so that it works with a null list of arguments. Use the "most elegant" way you can think of... The solution presented elsewhere using rowSums is probably the best, though, if you can be sure that you are only dealing with vectors and they all have the same length. The advantage of going about it the way outlined above is that the recycling rule kicks in if you need it, or if you are dealing with more general arrays the answer has the right shape. Bill Venables.