我在R中有一个数组,由这样的函数创建:
A <- array(data=NA, dim=c(2,4,4), dimnames=list(c("x","y"),NULL,NULL))
我想沿着一个维度选择,所以对于上面的例子,我会:
A["x",,]
dim(A["x",,]) #[1] 4 4
如果我事先不知道我的数组可能有多少维度(除了我想要选择的那个维度之外),还有一种方法可以概括吗?我想编写一个函数来获取可能格式化为A的输入,或者:
B <- c(1,2)
names(B) <- c("x", "y")
C <- matrix(1, 2, 2, dimnames=list(c("x","y"),NULL))
一般背景是我正在研究ODE模型,因此对于deSolve的ODE函数,它必须采用具有当前状态的单个命名向量。对于其他一些函数,比如计算相位平面/方向场,使用更高维数组来应用微分方程更为实际,我希望避免使用相同函数的多个副本,只需使用不同的函数我想要选择的维度之后的逗号数量。
答案 0 :(得分:10)
我花了很多时间找出为plyr做最快的方法,而我能想到的最好的方法是手动构建对[
的调用:
index_array <- function(x, dim, value, drop = FALSE) {
# Create list representing arguments supplied to [
# bquote() creates an object corresponding to a missing argument
indices <- rep(list(bquote()), length(dim(x)))
indices[[dim]] <- value
# Generate the call to [
call <- as.call(c(
list(as.name("["), quote(x)),
indices,
list(drop = drop)))
# Print it, just to make it easier to see what's going on
print(call)
# Finally, evaluate it
eval(call)
}
(您可以在https://github.com/hadley/devtools/wiki/Computing-on-the-language)
找到有关此技术的更多信息然后您可以按如下方式使用它:
A <- array(data=NA, dim=c(2,4,4), dimnames=list(c("x","y"),NULL,NULL))
index_array(A, 2, 2)
index_array(A, 2, 2, drop = TRUE)
index_array(A, 3, 2, drop = TRUE)
如果你想基于多个维度进行提取,它也会以简单的方式推广,但你需要重新考虑函数的参数。
答案 1 :(得分:4)
我写了这个一般功能。不一定非常快,但是arrayInd
和矩阵索引的一个很好的应用程序:
extract <- function(A, .dim, .value) {
val.idx <- match(.value, dimnames(A)[[.dim]])
all.idx <- arrayInd(seq_along(A), dim(A))
keep.idx <- all.idx[all.idx[, .dim] == val.idx, , drop = FALSE]
array(A[keep.idx], dim = dim(A)[-.dim], dimnames = dimnames(A)[-.dim])
}
示例:
A <- array(data=1:32, dim=c(2,4,4),
dimnames=list(c("x","y"), LETTERS[1:4], letters[1:4]))
extract(A, 1, "x")
extract(A, 2, "D")
extract(A, 3, "b")
答案 2 :(得分:2)
也许有一种更简单的方法,但这有效:
do.call("[",c(list(A,"x"),lapply(dim(A)[-1],seq)))
[,1] [,2] [,3] [,4]
[1,] NA NA NA NA
[2,] NA NA NA NA
[3,] NA NA NA NA
[4,] NA NA NA NA
让我们将它概括为一个可以从任何维度中提取的函数,而不一定是第一个维度:
extract <- function(A, .dim, .value) {
idx.list <- lapply(dim(A), seq_len)
idx.list[[.dim]] <- .value
do.call(`[`, c(list(A), idx.list))
}
示例:
A <- array(data=1:32, dim=c(2,4,4),
dimnames=list(c("x","y"), LETTERS[1:4], letters[1:4]))
extract(A, 1, "x")
extract(A, 2, "D")
extract(A, 3, "b")
答案 3 :(得分:2)
除了其他非常有用的数组操作函数之外,abind包还有一个函数asub
来执行此操作:
library(abind)
A <- array(data=1:32, dim=c(2,4,4),
dimnames=list(c("x","y"), LETTERS[1:4], letters[1:4]))
asub(A, 'x', 1)
asub(A, 'D', 2)
asub(A, 'b', 3)
它允许多维索引:
asub(A, list('x', c('C', 'D')), c(1,2))