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?
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