0

Let's say that we have the following list with some matrices inside (it could be many but for simplicity, I'm putting two for now)

> rel$E
      i   j   value             
 [1,] "3" "5" "0.070711136732969"  
 [2,] "3" "6" "0.0555555555555557" 
 [3,] "1" "3" "0.0178395371187627" 
 [4,] "1" "2" "0.00488002262797937"
 [5,] "2" "5" "0.0272189957856598" 
 [6,] "3" "4" "0.0438244348035453" 
 [7,] "2" "4" "0.0128664170608579" 
 [8,] "3" "3" "0"                  
 [9,] "2" "3" "0.0167431138932832" 
[10,] "2" "2" "0"                  
[11,] "4" "5" "0.0180208592355387" 
[12,] "2" "6" "0.028063474878704"  
[13,] "1" "5" "0.00937210021651717"
[14,] "1" "4" "0.0033698603568658" 
> rel$D
      i   j   value             
 [1,] "1" "3" "0.0398765637816322" 
 [2,] "1" "1" "0"                  
 [3,] "1" "4" "0.00452411512576561"
 [4,] "3" "4" "0.0193536780493677" 
 [5,] "1" "2" "0.00289466496926153"
 [6,] "2" "5" "0.0283053038069326" 
 [7,] "3" "3" "0"                  
 [8,] "3" "6" "0.0862179235688977" 
 [9,] "1" "5" "0.0242662144621697" 
[10,] "1" "6" "0.00584795321637427"
[11,] "4" "5" "0.0174208488656519" 
[12,] "2" "3" "0.0443079152300233" 
[13,] "2" "2" "0"                  
[14,] "2" "4" "0.0131264776661371" 
[15,] "3" "5" "0.0952553775375157" 

What I want to achieve is, to sum up, all values columns of the matrix that have the same i & j.

For example for i=3, j=5 the sum should be 0.070711136732969 + 0.0952553775375157.

But there are some pairs as you can see that exist to one but not to the other matrix.

For such a case i=1, j=6 the sum should be 0 + 0.00584795321637427 because this pair doesn't exist in the first matrix.

Is there any efficient (lapply,apply) way to produce a final matrix with columns i, j, sum? But without using many for loops? I tried to approached it with for loops but the final code became hard to read and change.

J. Doe
  • 619
  • 4
  • 16
  • `aggregate()` is your friend. https://stackoverflow.com/questions/3505701/grouping-functions-tapply-by-aggregate-and-the-apply-family Your data seems to be a matrix - so you eventually have to coerce to a dataframe. – jogo Feb 23 '18 at 13:34

1 Answers1

1

You need to rbind and aggregate, i.e.

aggregate(value ~ i+j, do.call(rbind, l2), sum)

which gives,

   i j       value
1  1 1 0.000000000
2  1 2 0.007774688
3  2 2 0.000000000
4  1 3 0.057716101
5  2 3 0.061051029
6  3 3 0.000000000
7  1 4 0.007893975
8  2 4 0.025992895
9  3 4 0.063178113
10 1 5 0.033638315
11 2 5 0.055524300
12 3 5 0.165966514
13 4 5 0.035441708
14 1 6 0.005847953
15 2 6 0.028063475
16 3 6 0.141773479

DATA

dput(l2)
list(structure(c(3, 3, 1, 1, 2, 3, 2, 3, 2, 2, 4, 2, 1, 1, 5, 
6, 3, 2, 5, 4, 4, 3, 3, 2, 5, 6, 5, 4, 0.070711136732969, 0.0555555555555557, 
0.0178395371187627, 0.00488002262797937, 0.0272189957856598, 
0.0438244348035453, 0.0128664170608579, 0, 0.0167431138932832, 
0, 0.0180208592355387, 0.028063474878704, 0.00937210021651717, 
0.0033698603568658), .Dim = c(14L, 3L), .Dimnames = list(NULL, 
    c("i", "j", "value"))), structure(c(1, 1, 1, 3, 1, 2, 3, 
3, 1, 1, 4, 2, 2, 2, 3, 3, 1, 4, 4, 2, 5, 3, 6, 5, 6, 5, 3, 2, 
4, 5, 0.0398765637816322, 0, 0.00452411512576561, 0.0193536780493677, 
0.00289466496926153, 0.0283053038069326, 0, 0.0862179235688977, 
0.0242662144621697, 0.00584795321637427, 0.0174208488656519, 
0.0443079152300233, 0, 0.0131264776661371, 0.0952553775375157
), .Dim = c(15L, 3L), .Dimnames = list(NULL, c("i", "j", "value"
))))
Sotos
  • 51,121
  • 6
  • 32
  • 66
  • Thank you very much. Just to add that I had to convert my matrix into numeric for the sum function to work. – J. Doe Feb 23 '18 at 13:54