lightsnail
lightsnail

Reputation: 788

Calculate the conditional proportions in a list

j is a list made of matrices.

j <- list(matrix(1:12,3),matrix(50:61,3))

> j
[[1]]
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

[[2]]
     [,1] [,2] [,3] [,4]
[1,]   50   53   56   59
[2,]   51   54   57   60
[3,]   52   55   58   61

k is also a list made of matrices.

k <- list(matrix(c(T,T,T,T,T,T,F,T,F,F,F,F),3,byrow = T),
          matrix(c(T,F,T,F,F,T,T,T,F,F,F,F),3,byrow = T))

> k
[[1]]
      [,1]  [,2]  [,3]  [,4]
[1,]  TRUE  TRUE  TRUE  TRUE
[2,]  TRUE  TRUE FALSE  TRUE
[3,] FALSE FALSE FALSE FALSE

[[2]]
      [,1]  [,2]  [,3]  [,4]
[1,]  TRUE FALSE  TRUE FALSE
[2,] FALSE  TRUE  TRUE  TRUE
[3,] FALSE FALSE FALSE FALSE

j and k have the same dimensions. In each row, I want to calculate the values of j divided by the sum of TRUE j.

Let me explain it with examples:

The first row in the first object of j is 1 4 7 10, and the corresponding row of k is TRUE TRUE TRUE TRUE, since all the corresponding js are all true, so the sum of "True" j is 1+4+7+10 = 22, so the values of j divided by the sum of "True" j is 1/22 4/22 7/22 10/22, that is 0.04545455 0.18181818 0.31818182 0.45454545.

Another example: the second row in the first object of j is 2 5 8 11, and the corresponding row of k is TRUE TRUE FALSE TRUE, so the sum of "True" j is 2+5+11 = 18, so the values of j divided by the sum of "True" j is 2/18 5/18 8/18 11/18, that is 0.1111111 0.2777778 0.4444444 0.6111111.

So the final expected result is:

[[1]]
              [,1]       [,2]       [,3]       [,4]
[1,]    0.04545455 0.18181818 0.31818182 0.45454545
[2,]    0.1111111  0.2777778  0.4444444  0.6111111
[3,]           Inf        Inf        Inf        Inf

[[2]]
              [,1]       [,2]       [,3]       [,4]
[1,]     0.4716981  0.5000000  0.5283019  0.5566038
[2,]     0.2982456  0.3157895  0.3333333  0.3508772
[3,]           Inf        Inf        Inf        Inf

I find that the Map(function(a,b) a[b], j, k) can extract the all the true values, but I don't know how to sum them row by row,

Upvotes: 1

Views: 112

Answers (2)

akuiper
akuiper

Reputation: 214927

You can use Map and rowSums, Map is used to loop through j and k at the same time, and rowSums can be used to calculate the conditional sum of rows by simply multiplying matrices in j with matrices in k:

Map(function(x,y) x/rowSums(x*y), j, k)

# [[1]]
#            [,1]      [,2]      [,3]      [,4]
# [1,] 0.04545455 0.1818182 0.3181818 0.4545455
# [2,] 0.11111111 0.2777778 0.4444444 0.6111111
# [3,]        Inf       Inf       Inf       Inf
# 
# [[2]]
#           [,1]      [,2]      [,3]      [,4]
# [1,] 0.4716981 0.5000000 0.5283019 0.5566038
# [2,] 0.2982456 0.3157895 0.3333333 0.3508772
# [3,]       Inf       Inf       Inf       Inf

Upvotes: 3

989
989

Reputation: 12937

Try this:

lapply(seq_len(length(j)), function(i) j[[i]]/rowSums(j[[i]]*k[[i]]))

#[[1]]
#           [,1]      [,2]      [,3]      [,4]
#[1,] 0.04545455 0.1818182 0.3181818 0.4545455
#[2,] 0.11111111 0.2777778 0.4444444 0.6111111
#[3,]        Inf       Inf       Inf       Inf

#[[2]]
#          [,1]      [,2]      [,3]      [,4]
#[1,] 0.4716981 0.5000000 0.5283019 0.5566038
#[2,] 0.2982456 0.3157895 0.3333333 0.3508772
#[3,]       Inf       Inf       Inf       Inf

Upvotes: 1

Related Questions