8

Suppose I have two lists, and corresponding elements of the lists are the same shape:

 e1=list(1,c(1,2,3),matrix(1:12,3,4))
 e2=list(1,c(1,2,3),matrix(1:12,3,4))

and I want to add these two lists element-by-element. Here's my solution which works for any length of lists and any shape of element, as long as they match and are addable:

> esum
function(e1,e2){
  e = list()
  for(i in 1:length(e1)){
    e[[i]]=e1[[i]]+e2[[i]]
  }
  e
}
> esum(e1,e2)

but it just seems ugly, and probably the kind of thing that can be done in a one-liner.

This is stage one of the problem, which is actually to add up a whole list of many of these lists, but once esum is defined its just Reduce:

 > ee = list(e1,e2,e1,e1,e2)
 > Reduce(esum,ee)[[3]]  # lets just check [[3]] for now
      [,1] [,2] [,3] [,4]
 [1,]    5   20   35   50
 [2,]   10   25   40   55
 [3,]   15   30   45   60

So, anyone got a one-liner for these?

Yes I know one-liners aren't always the best things.

Spacedman
  • 92,590
  • 12
  • 140
  • 224

2 Answers2

18

Something like

   mapply("+",e1,e2)

works for the first part ...

Reduce( function(x,y) mapply("+",x,y),ee)[[3]]

There may be something even slicker. Reduce doesn't take a ... argument so we can't get away with Reduce(mapply,ee,FUN="+")[[3]]

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • You could do `ee3 <- list(e1[[3]], e2[[3]], e3[[3]]) ; Reduce('+',ee3)` although that would require a line or two of script to cycle through all the elements of e* . – Carl Witthoft Oct 26 '11 at 13:46
  • The [[3]] was just so I didn't spew out the whole result. I'm actually interested in all the sums – Spacedman Oct 26 '11 at 13:53
  • 2
    cool solution! you can define `esum` as a higher order function using `esum <- function(...) mapply("+", ...)` and then just do `Reduce(esum, ee)` – Ramnath Oct 26 '11 at 15:19
  • 3
    FYI `Map` is usually safer than `mapply` since it always returns a list. – hadley Feb 26 '13 at 15:39
0

How about: esum <- unlist(e1) + unlist(e2)

You will have to 'rebuild' your list structure, which is easy if you always have the same structure, and will take just a little work if you're dealing with arbitrary structures.

Ahhh, forget it. The mapply('+',...) solution is nicer and beat me to the punch.

Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73