使用索引向量对数组进行子集 [英] Subset an array using a vector of indices

查看:37
本文介绍了使用索引向量对数组进行子集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用索引向量对数组进行子集化?举个例子可能更容易说明这一点.

# 我有这个数组bn <-结构(c(0.8, 0.09, 0.11, 0.09, 0.8, 0.11, 0.11, 0.11, 0.78,0.18, 0.13, 0.69, 0.88, 0.07, 0.05, 0.25, 0.49, 0.26, 0.43, 0.2,0.37, 0.34, 0.39, 0.27, 0.13, 0.44, 0.42), class = "table", .Dim = c(3L,3L, 3L), .Dimnames = structure(list(D = c("a", "b", "c"), A = c("a","b", "c"), C = c("a", "b", "c")), .Names = c("D", "A", "C")))# 和索引矩阵(对应 bn 的维度)输入 <- 结构(c(a",b",NA),.Dim = c(1L,3L),.Dimnames = list(NULL, c("A", "C", "D")))

我可以通过直接索引给出结果来子集bn

bn[, input[,"A"], input[,"C"]]# a b c# 0.18 0.13 0.69

如何在不像这样分解的情况下执行此操作(虽然我事先不知道数组的维数,但它将是输入数 + 1).基于 r-subset-array-using-vector(虽然这个问题是针对列表不是数组),我试过

bn[, input[,c("A","C")]]bn[, input[,c("A","C"), drop=FALSE]]

<块引用>

[.default(bn, input[, c("A", "C"), drop = FALSE], ) 中给出错误:
维数不正确

这行得通,但会在强制上花费太多时间并构建索引.

库(R.utils)x = 数组(bn,dim=dim(bn),dimnames=dimnames(bn))提取(x,索引=列表(2"=1,3"=2))

我也可以melt数据,然后拉出相关的行,然后还有这个问题 subset-an-array-for-r 中的指数对]但该解决方案以数组的维数为前提.

是否有一种简洁的方法可以通过对 array 进行子集化来做到这一点?

<小时>

另一种选择:

库(gRbase)inp = input[,c("A", "C"), drop=FALSE]ar_slice(bn, split(inp, colnames(inp)))

但是如果没有 split

的工作就好了

或在 r2evans 中领先

ar_slice(bn, setNames(as.list(inp), colnames(inp)))

解决方案

一种方法,虽然它看起来并不那么漂亮.

do.call(`[`, c(list(bn), list(TRUE), as.list(input[,c("A","C")])))# a b c# 0.18 0.13 0.69

我会追踪我是如何想出这个的.

  1. 最初,我们只需要 bn[,"a","b"].意识到这与 db[TRUE,"a","b"] 相同.
  2. [ 翻译成一个函数,ala `[<-`(bn, TRUE, "a", "b").
  3. 知道要动态生成参数列表,瞬间想到了do.call,所以要知道如何创建(bn, TRUE, "a", "b") 以编程方式.最后一部分是:

    as.list(input[,c("A","C")])# $A# [1] "一个"# $C# [1] "b"

    所以我们可以通过在 list-ified bnTRUE 前面添加来创建整个参数:

    str( c(list(bn), list(TRUE), as.list(input[,c("A","C")])) )# 4 个列表# $ : 'table' num [1:3, 1:3, 1:3] 0.8 0.09 0.11 0.09 0.8 0.11 0.11 0.11 0.78 0.18 ...# ..- attr(*, "dimnames")=3 的列表# .. ..$ D: chr [1:3] "a" "b" "c"# .. ..$ A: chr [1:3] "a" "b" "c"# .. ..$ C: chr [1:3] "a" "b" "c"# $ : logi TRUE# $ A: chr "a"# $ C: chr "b"

这是假设你的第一个轴总是满"(TRUE).如果您需要动态确定,只需知道 do.call 中列表的第二个及以上元素是您的轴,根据您的需要确定它们.

How can I subset an array using a vector of indices? This may be easier to show by an example.

# I have this array
bn <- structure(c(0.8, 0.09, 0.11, 0.09, 0.8, 0.11, 0.11, 0.11, 0.78, 
0.18, 0.13, 0.69, 0.88, 0.07, 0.05, 0.25, 0.49, 0.26, 0.43, 0.2, 
0.37, 0.34, 0.39, 0.27, 0.13, 0.44, 0.42), class = "table", .Dim = c(3L, 
3L, 3L), .Dimnames = structure(list(D = c("a", "b", "c"), A = c("a", 
"b", "c"), C = c("a", "b", "c")), .Names = c("D", "A", "C")))    

# and matrix of indices (correspond to dimensions of bn)
input <- structure(c("a", "b", NA), .Dim = c(1L, 3L), 
                   .Dimnames = list(NULL, c("A", "C", "D")))

I can subset bn by directly indexing to give the result

bn[, input[,"A"], input[,"C"]]
#    a    b    c 
# 0.18 0.13 0.69 

How can I do this without decomposing it like this (while I won't know before hand the dimension of the array, it will be the number of inputs + 1). Based on r-subset-array-using-vector(although that question is for a list not an array), I tried

bn[, input[,c("A","C")]]
bn[, input[,c("A","C"), drop=FALSE]]

which give Error in [.default(bn, input[, c("A", "C"), drop = FALSE], ) :
incorrect number of dimensions

This works , but will involve too much time being spent on coercing and constructing indices.

library(R.utils)
x = array(bn, dim=dim(bn), dimnames=dimnames(bn))
extract(x, indices=list("2"=1, "3"=2))

I could also melt the data and then pull out the relevant rows, and there is also this question subset-an-array-for-the-pairs-of-indices-in-r] but the solution presupposes the dimensions of the array.

Is there a succinct way to do this by subsetting the array?


An another option:

library(gRbase)
inp = input[,c("A", "C"), drop=FALSE]
ar_slice(bn, split(inp, colnames(inp)))

But it would be nice without the work of split

or taking a lead from r2evans

ar_slice(bn, setNames(as.list(inp), colnames(inp)))

解决方案

One method, though it doesn't really look that pretty.

do.call(`[`, c(list(bn), list(TRUE), as.list(input[,c("A","C")])))
#    a    b    c 
# 0.18 0.13 0.69 

I'll trace how I came up with that.

  1. Initially, we want just bn[,"a","b"]. Realize that this is identical to db[TRUE,"a","b"].
  2. Translate the [ to a function, ala `[<-`(bn, TRUE, "a", "b").
  3. Knowing that you want to generate the argument list dynamically, I instantly think of do.call, so we need to know how to create (bn, TRUE, "a", "b") programmatically. The last part is:

    as.list(input[,c("A","C")])
    # $A
    # [1] "a"
    # $C
    # [1] "b"
    

    so we can create the whole slew of arguments by prepending list-ified bn and TRUE:

    str( c(list(bn), list(TRUE), as.list(input[,c("A","C")])) )
    # List of 4
    #  $  : 'table' num [1:3, 1:3, 1:3] 0.8 0.09 0.11 0.09 0.8 0.11 0.11 0.11 0.78 0.18 ...
    #   ..- attr(*, "dimnames")=List of 3
    #   .. ..$ D: chr [1:3] "a" "b" "c"
    #   .. ..$ A: chr [1:3] "a" "b" "c"
    #   .. ..$ C: chr [1:3] "a" "b" "c"
    #  $  : logi TRUE
    #  $ A: chr "a"
    #  $ C: chr "b"
    

This is assuming that your first axis is always "full" (TRUE). If you need to determine that dynamically, just know that the 2nd-and-beyond elements of the list within do.call are your axes, determine them as you deem necessary.

这篇关于使用索引向量对数组进行子集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆