Reputation: 1254
I have a matrix which I want to put into an apply function and use the location and value of each object in the matrix to select and update positions in a 3 dimensional array. I can do this very easily in a for loop, but I am curious if it is possible to do it in an apply function. I seem to be having trouble wrapping my head around that. I have some things that work, but not ideally.
foo <- matrix(c(3, NA, NA, 1, NA, 3, NA, 2, NA),
3, 3, byrow = TRUE)
bar <- array(NA, c(3, 3, 3))
This is the for loop that does exactly what I am looking for
for (i in 1:3){
for (j in 1:3){
if (!is.na(foo[i, j])){
bar[i, j, foo[i, j]] <- TRUE
}
}
}
This is the best that I have gotten so far. It does update the array, but it prints out a list of the assignments made at each iteration. Also if it is possible to do this without the <<-
operator, that would be ideal.
fillArray <- function(x) {
if (!is.na(foo[x[1], x[2]])) {
bar[x[1], x[2], foo[x[1], x[2]]] <<- TRUE
}
}
apply(expand.grid(1:3, 1:3), 1, fillArray)
I would like to get the same result as the for loop does.
Upvotes: 0
Views: 175
Reputation: 887951
It is easier to construct a three column i, j, k
matrix index and then do the assignment
# index matrix
m1 <- cbind(as.matrix(expand.grid(1:3, 1:3)), c(foo))
bar1 <- bar # initial data
# remove the NA rows of the third column of index
bar1[m1[!is.na(m1[,3]),, drop = FALSE]] <- TRUE
-checking with the output from OP
identical(bar, bar1)
#[1] TRUE
Upvotes: 1