Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently finding minimum cells values from a set of matrices in R

Tags:

r

I have a list of matrices (size n*n), and I need to create a new matrix giving the minimum value observed for each cell, based on my list.

For instance, with the following matrices list:

> a = list(matrix(rexp(9), 3), matrix(rexp(9), 3), matrix(rexp(9), 3))
> a
[[1]]
          [,1]       [,2]       [,3]
[1,] 0.5220069 0.39643016 0.04255687
[2,] 0.4464044 0.66029350 0.34116609
[3,] 2.2495949 0.01705576 0.08861866

[[2]]
          [,1]     [,2]      [,3]
[1,] 0.3823704 0.271399 0.7388449
[2,] 0.1227819 1.160775 1.2131681
[3,] 0.1914548 1.004209 0.7628437

[[3]]
          [,1]       [,2]      [,3]
[1,] 0.2125612 0.45379057 1.5987420
[2,] 0.3242311 0.02736743 0.4372894
[3,] 0.6634098 1.15401347 0.9008529

The output should be:

          [,1]       [,2]      [,3]
[1,] 0.2125612 0.271399 0.04255687
[2,] 0.1227819 0.02736743 0.34116609
[3,] 0.1914548 0.01705576 0.08861866

I tried using apply loop with the following code (using melt and dcast from reshape2 library):

library(reshape2)
all = melt(a)
allComps = unique(all[,c(1:2)])
allComps$min=apply(allComps, 1, function(x){
  g1 = x[1]
  g2 = x[2]
  b = unlist(lapply(a, function(y){
    return(y[g1,g2])
  }))
  return(b[which(b==min(b))])
})
dcast(allComps, Var1~Var2) 

It works but it is taking a very long time to run when applied on large matrices (6000*6000). I am looking for a faster way to do this.

like image 649
chachou Avatar asked Mar 01 '23 14:03

chachou


2 Answers

Use Reduce with pmin :

Reduce(pmin, a)

#           [,1]       [,2]      [,3]
#[1,] 0.02915345 0.03157736 0.3142273
#[2,] 0.57661027 0.05621098 0.1452668
#[3,] 0.48021473 0.18828404 0.4787604

data

set.seed(123)
a = list(matrix(rexp(9), 3), matrix(rexp(9), 3), matrix(rexp(9), 3))
like image 113
Ronak Shah Avatar answered Apr 24 '23 04:04

Ronak Shah


Maybe it should be considered to store the matrices in an array instead of a list. This can be done with simplify2array. In an array the minimum over specific dimensions can be found using min in apply.

A <- simplify2array(a)
apply(A, 1:2, min)
like image 34
GKi Avatar answered Apr 24 '23 04:04

GKi