14

次のような関数によって作成されたRの配列があります。

A <- array(data=NA, dim=c(2,4,4), dimnames=list(c("x","y"),NULL,NULL))

そして、1つの次元に沿って選択したいので、上記の例では次のようになります:

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 関数では、現在の状態で単一の名前付きベクトルを取得する必要があります。位相面/方向場の計算などの他の関数については、微分方程式を適用する高次元の配列を使用する方が実際的であり、単純に異なる関数を使用して同じ関数のコピーを多数作成することは避けたいと考えています。選択したい次元の後のコンマの数。

4

4 に答える 4

11

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)

複数の次元に基づいて抽出する場合も、簡単な方法で一般化できますが、関数への引数を再考する必要があります。

于 2013-01-24T13:19:29.120 に答える
5

この一般的な関数を書きました。必ずしも超高速というわけではありませんが、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")
于 2013-01-24T12:32:20.287 に答える
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")
于 2013-01-24T12:20:25.487 に答える