Skip to content

Instantly share code, notes, and snippets.

@dewittpe
Last active October 27, 2017 17:20
Show Gist options
  • Save dewittpe/229567bfe462deb05f1e12b5ad00e05a to your computer and use it in GitHub Desktop.
Save dewittpe/229567bfe462deb05f1e12b5ad00e05a to your computer and use it in GitHub Desktop.
Custom extractor function
# my_extractor.R
#
# Given an M dimensional array, extract the last index based on prescribed
# values of the first M-1 values.
#
# For example, for a 3D array with indices [x, y, z] write a function that will
# extract z as function of x and y.
set.seed(42)
################################################################################
# 2D example
Amat <- matrix(rnorm(25), nrow = 5)
Amat
# etract a different column value for each row
v <- cbind(1:5, c(3, 2, 1, 5, 5))
v
# use apply to extract the elements as wanted
apply(v, 1, function(x, mat) {mat[x[1], x[2]]}, mat = Amat)
# note that `[` is really a function.
apply(v, 1, function(x, mat) {`[`(mat, x[1], x[2])}, mat = Amat)
################################################################################
# A general function
my_extractor <- function(x, dat) {
apply(x, 1,
function(xx) {
do.call(`[`, c(list(dat), split(xx, seq_along(xx))))
})
}
# check
my_extractor(v, Amat)
all.equal(my_extractor(v, Amat),
apply(v, 1, function(x, mat) {`[`(mat, x[1], x[2])}, mat = Amat)
)
################################################################################
# set up an example 3D Array, elements are three digit numbers of the form xyz
# with x representing the row, y the column, and z the depth
A <- expand.grid(a = 1:5, b = 1:8, c = 1:3)
A <- apply(A, 1, paste, collapse = "")
A <- array(A, dim = c(5, 8, 3))
A
# example vector for which element of z is selected for each xy com
v <- expand.grid(x = 1:2, y = 1:3)
v <- cbind(v, z = sample(1:3, nrow(v), replace = TRUE))
v
my_extractor(v, A)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment