Search code examples
rapplysimulationrepeat

Fill a NA array using apply functions


I want to fill an array using the apply function.

For example, my purpose is to simplify the repetition in the following code

tmp <- matrix(1:100, 20, 5)
i <- replicate(2, sample(1:nrow(tmp), 3))
dt <- array(NA, c(3, 5, 2))

# the repetition:
dt[, , 1] <- tmp[i[,1], ]
dt[, , 2] <- tmp[i[,2], ]

The following may be a solution:

for (s in 1:2) {
 dt[, , s] <- tmp[i[,s], ]
}

But, I do not want to use the for loop.

The purpose is to make pseudo data sets for a simulation.

That is, "tmp" is a matrix for the population with 20 individuals and 5 variables.

And, each column of "i" is the index of sampled persons for two iteration of the simulation.

Thus, I am trying to stake the two samples in an array.

Here, how can I make the line two lines in the code just one line?

For this, I think, apply function may be a candidate.

Can we reduce the last lines?

(This question is closely related to Fill a NA matrix using apply functions. But, the solution might be pretty different. )


Solution

  • Instead of filling dt, subset tmp by using i in apply and create the array with desired dimensions.

    (dt <- array(apply(i, 2, \(x) tmp[x, ]), dim=c(3, 5, 2)))
    # , , 1
    # 
    #      [,1] [,2] [,3] [,4] [,5]
    # [1,]   14   34   54   74   94
    # [2,]    4   24   44   64   84
    # [3,]   15   35   55   75   95
    # 
    # , , 2
    # 
    #      [,1] [,2] [,3] [,4] [,5]
    # [1,]   15   35   55   75   95
    # [2,]   19   39   59   79   99
    # [3,]   20   40   60   80  100
    

    Your for loop, however, is perfectly fine and well understandable.


    Data:

    tmp <- structure(1:100, dim = c(20L, 5L))
    i <- structure(c(14L, 4L, 15L, 15L, 19L, 20L), dim = 3:2)