Home > Net >  Matrix generation based on list's objects in R
Matrix generation based on list's objects in R

Time:04-12

I have a list of objects in R like follows:

set.seed(1234)
data <- matrix(rnorm(3*4,mean=0,sd=1), 3, 4) 
results <- lapply(1:ncol(data), function(i) outer(data[, i], data[, i]))

which will result in the following matrices

[[1]]
           [,1]        [,2]       [,3]
[1,]  1.4570077 -0.33487534 -1.3089918
[2,] -0.3348753  0.07696698  0.3008557
[3,] -1.3089918  0.30085569  1.1760127

[[2]]
          [,1]       [,2]       [,3]
[1,]  5.502298 -1.0065968 -1.1870541
[2,] -1.006597  0.1841480  0.2171611
[3,] -1.187054  0.2171611  0.2560926

[[3]]
          [,1]      [,2]      [,3]
[1,] 0.3303260 0.3141712 0.3244131
[2,] 0.3141712 0.2988064 0.3085474
[3,] 0.3244131 0.3085474 0.3186061

[[4]]
          [,1]      [,2]      [,3]
[1,] 0.7921673 0.4247196 0.8886017
[2,] 0.4247196 0.2277129 0.4764227
[3,] 0.8886017 0.4764227 0.9967755

How can I create a single matrix containing the Interquartile Range (IQR) between the corresponding elements? Meaning the new matrix will be a B=3X3 matrix with for example B(1,1)=IQR(c(1.4570077,5.502298,0.3303260,0.7921673))=1.791623, B(1,2)=IQR(c(-0.33487534, -1.0065968, 0.3141712, 0.4247196))= 0.844614. How can I use the apply function to create this new matrix?

CodePudding user response:

We may convert the list to array and then use apply with MARGIN as c(1, 2) and apply the IQR elementwise

apply(simplify2array(results), c(1, 2), IQR)

-output

      [,1]       [,2]       [,3]
[1,] 1.791623 0.84461397 1.68299882
[2,] 0.844614 0.08813351 0.07058422
[3,] 1.682999 0.07058422 0.73860710

Or another option is transpose the list and then apply the IQR by looping over the list

library(purrr)
`dim<-`(map_dbl(transpose(results), IQR), dim(results[[1]]))
         [,1]       [,2]       [,3]
[1,] 1.791623 0.84461397 1.68299882
[2,] 0.844614 0.08813351 0.07058422
[3,] 1.682999 0.07058422 0.73860710
  • Related