[SOLVED] Fast fill 3D array/matrix in R with known index and value

Issue

may I ask a stupid question about fast assigning values to a big 3D matrix in R? I have x, y, z for location index and val for values to fill. The for loop takes so long, could you please help? Note that here I just simulated xyz and val

x <- replicate(1e4, sample(seq(1:100), size = 1))
y <- replicate(1e4, sample(seq(1:100), size = 1))
z <- replicate(1e4, sample(seq(1:200), size = 1))
val <- rnorm(1e4, 0, 1)

a <- array(numeric(),c(100, 100, 200))
for(ii in seq(from = 1, to = length(x), by = 1)){
    a[x[ii], y[ii], z[ii]] <- val[ii]
}

I tied the following mapply but it returns to me a vector

mapply(function(i, j, k, v) a[i, j, k] <- v, x, y , z, val)

Solution

You can do

a[cbind(x, y, z)] <- val

It’s difficult to show that this works on such a large example, so let’s demonstrate on a smaller scale with a 3 x 3 x 3 matrix:

a <- array(numeric(), c(3, 3, 3))

x <- c(3, 2, 1)
y <- c(1, 1, 1)
z <- c(1, 2, 3)
val <- c(1, 2, 3)

So these variables imply that we want a one in the third row of the first column of our first slice, a two in the second row of the first column of our second slice, and a three in the first row of the first column of our third slice:

a[cbind(x, y, z)] <- val

a
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]   NA   NA   NA
#> [2,]   NA   NA   NA
#> [3,]    1   NA   NA
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]   NA   NA   NA
#> [2,]    2   NA   NA
#> [3,]   NA   NA   NA
#> 
#> , , 3
#> 
#>      [,1] [,2] [,3]
#> [1,]    3   NA   NA
#> [2,]   NA   NA   NA
#> [3,]   NA   NA   NA

Created on 2022-02-24 by the reprex package (v2.0.1)

Answered By – Allan Cameron

Answer Checked By – Jay B. (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *