【问题标题】:Convert vector to array index in R?将向量转换为R中的数组索引?
【发布时间】:2020-05-14 23:29:03
【问题描述】:

假设我们有一个数组 A,它具有任意维度 dim(A)。假设我们有一个坐标索引向量 V。有没有什么方法可以访问坐标为 V 的 A 的元素?做类似 A[V] 的事情显然不起作用。如果 V=c(1,2,3) 那么 A[V] 只会给我们 A 的第一个、第二个和第三个元素。如果我们想要 A[1,2,3] 怎么办?如果我们提前知道 dim(A),这显然很容易。但是,如果我们想让代码不管 A 有多少维都可以工作呢?

【问题讨论】:

    标签: r arrays multidimensional-array


    【解决方案1】:

    我们可以使用do.call 来执行`[`

    v <- c(1, 2, 3)
    
    do.call(`[`, c(list(A), v))
    # [1] 22
    

    要分配我们有`[&lt;-`

    A <- do.call(`[<-`, c(list(A), v, 99))
    

    检查:

    A[,,3]
    # , , 3
    # 
    # [,1] [,2] [,3]
    # [1,]   19   99   25
    # [2,]   20   23   26
    # [3,]   21   24   27
    

    使用 @duckmayr 的 A

    A <- array(1:(3^3), dim = c(3, 3, 3))
    

    【讨论】:

    • 不错!没想到使用do.call()。相当被低估的命令,我通常会发现
    【解决方案2】:

    你可以使用eval(parse()),像这样:

    foo <- function(A, v) {
        stopifnot(length(v) == length(dim(A)))
        idx <- paste(v, collapse = ", ")
        return(eval(parse(text = paste0("A[", idx, "]"))))
    }
    
    A <- array(1:(3^3), dim = c(3, 3, 3))
    v <- c(1, 2, 3)
    
    foo(A, v)
    # [1] 22
    A[1, 2, 3]
    # [1] 22
    

    更新:作业

    在 cmets 中,您还会询问作业;看起来您已经对其进行了排序,但如果您或其他人发现它有用,您可以使用替换功能:

    `foo<-` <- function(A, v, value) {
        stopifnot(length(v) == length(dim(A)))
        stopifnot(is.atomic(value) & length(value) == 1)
        idx <- paste(v, collapse = ", ")
        eval(parse(text = paste0("A[", idx, "] <- value")))
        return(A)
    }
    
    foo(A, v) <- 2
    foo(A, v)
    # [1] 2
    

    【讨论】:

    • 但是如果我们想做赋值操作呢?所以 A[v] = 99?
    • 哦等等,parse+eval 也允许赋值。谢谢!!
    猜你喜欢
    • 2015-11-16
    • 2012-07-20
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 2023-01-14
    相关资源
    最近更新 更多