简体   繁体   中英

Accessing same matrix position from multiple matrices in a list in R?

I have a List of arbitrary length, all entries being matrices of arbitrary length and width but identically sized to each other. I would like to compute the mean, median, and mode of the values at the same position in every matrix in the list. I could do this with a for loop, but is there a simpler/vectorized way?

I tried:

for (x in 1:X){
   for (y in 1:Y){
      My_List[[B+1]][y,x] <- mean(My_List[[1:B]][y,x])
      My_List[[B+2]][y,x] <- median(My_List[[1:B]][y,x])
      My_List[[B+3]][y,x] <- mode(My_List[[1:B]][y,x])
   }
}

Where the list is of length B+3, and the matrices are all of width X and length Y, but I got errors relating to trying to access across list entries. I considered lapply(), but I don't know how to turn a sunsetting operation into a FUN for the apply() family. I could do this with an obscene nest of for loops, but there must be a better way, especially in R.

EDIT: Reproducible example and expected output:

Step 1: Generation of My_List:

Matrix_A <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 2)
Matrix_B <- matrix(c(2, 1, 3, 3, 6, 5), nrow = 2)
Matrix_C <- matrix(c(1, 1, 3, 3, 5, 5), nrow = 2)

# X = 3, Y = 2

B = 3

My_List <- vector(mode = "list", length = B + 3)

My_List[[1]] <- Matrix_A
My_List[[2]] <- Matrix_B
My_List[[3]] <- Matrix_C

My_List

Step 1 Output, note the NULL placeholder spaces:

[[1]]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

[[2]]
     [,1] [,2] [,3]
[1,]    2    3    6
[2,]    1    3    5

[[3]]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    1    3    5

[[4]]
NULL

[[5]]
NULL

[[6]]
NULL

Using the same code block as above, I expect to see My_List[[4]][1,1] be the mean of My_List[[1]][1,1], My_List[[2]][1,1], and My_List[[3]][1,1], so 1 + 2 + 1 / 3 = 1.333, and so on for every combination of y and x. Index 4 of the list will be for mean, 5 for median, and 6 for mode.

I expect the final output to be:

[[1]]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

[[2]]
     [,1] [,2] [,3]
[1,]    2    3    6
[2,]    1    3    5

[[3]]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    1    3    5

[[4]] # Mean
     [,1]     [,2]     [,3]
[1,]    1.333    3.000    5.333
[2,]    1.333    3.333    5.333

[[5]] # Median
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    1    3    5

[[6]] # Mode
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    1    3    5

You could transform the list of matrices to a 3 dimensional array:

i <- 2
j <- 3

n <- 4

# create list of n i*j matrices
l <- replicate(n, list(matrix(sample(10,i*j),i,j)))

# list to 3D array
arr.3d <- array(unlist(l), c(i, j, n))

apply(arr.3d, 1:2, mean)
     [,1] [,2] [,3]
[1,] 6.50 5.00 3.50
[2,] 5.25 4.25 6.75

apply(arr.3d, 1:2,median)
     [,1] [,2] [,3]
[1,]    6    5  1.5
[2,]    5    4  6.0

For mode :

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

apply(arr.3d,1:2,Mode)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM