使用列表矩阵为N维对象提供索引

时间:2017-08-02 19:31:18

标签: arrays r multidimensional-array

我正在研究偏微分方程项目,其中需要一些N维物体。我陷入了填充一个N-dim对象的问题,每个对象都有一个尺寸的副本。这是功能:

padreplicate <- function(a, padSize) {
    # Pad an array by replicating values.
    numDims <- length(padSize)
    idx <- vector("list", numDims)
    for (k in 1:numDims) {
        M <-  dim(a)[k]       # 32
        onesVector <-  ones(1, padSize[k])
        idx[[k]] <- c(onesVector, 1:M, M * onesVector)
    }
    # return(a[ unlist(idx[1]), unlist(idx[2]) ])  # this works for 2D
    # return(a[ idx[[1]], idx[[2]] ])              # this also works for 2D
    # return(a[apply(idx, 1, function(x) unlist[x])])  #:( doesn't work 
    # a[sapply(apply(idx, 1:length(dim(idx)), function(x) eval(parse(text=x))), unlist)] #:(

    # 2D: "a[idx[[1]], idx[[2]]]"     3D: "a[idx[[1]], idx[[2]]], idx[[3]]]"
    dim_text = paste0("a", "[ ", 
                      paste0(sapply(1:length(idx), function(x) 
                          paste0("idx", "[[", x, "]]")), collapse = ", ")," ]")
    eval(parse(text=dim_text))               # this works
}

第一个参数是N-dim对象;它可以是矩阵,3D阵列或更高维数组。

2D对象或矩阵的示例是:

# pad a matrix 4x3 with c(1,1)
set.seed(123456)
mx = matrix(sample.int(9, size = 9*100, replace = TRUE), nrow = 4, ncol = 3)
mx
  #       [,1] [,2] [,3]
  # [1,]    8    4    9
  # [2,]    7    2    2
  # [3,]    4    5    8
  # [4,]    4    1    6
padreplicate(mx, c(1,1))

填充矩阵如下所示:

      [,1] [,2] [,3] [,4] [,5]
[1,]    8    8    4    9    9
[2,]    8    8    4    9    9
[3,]    7    7    2    2    2
[4,]    4    4    5    8    8
[5,]    4    4    1    6    6
[6,]    4    4    1    6    6

对于三维数组输入数组和填充数组。

ar = array(sample.int(9, size = 9*100, replace = TRUE), dim = c(3, 3, 1))
ar
padreplicate(ar, c(1,1,1))

# input 3x3x1 array
, , 1

     [,1] [,2] [,3]
[1,]    3    4    6
[2,]    7    2    9
[3,]    3    4    8

   # padded 5x5x3 array
, , 1

     [,1] [,2] [,3] [,4] [,5]
[1,]    3    3    4    6    6
[2,]    3    3    4    6    6
[3,]    7    7    2    9    9
[4,]    3    3    4    8    8
[5,]    3    3    4    8    8

, , 2

     [,1] [,2] [,3] [,4] [,5]
[1,]    3    3    4    6    6
[2,]    3    3    4    6    6
[3,]    7    7    2    9    9
[4,]    3    3    4    8    8
[5,]    3    3    4    8    8

, , 3

     [,1] [,2] [,3] [,4] [,5]
[1,]    3    3    4    6    6
[2,]    3    3    4    6    6
[3,]    7    7    2    9    9
[4,]    3    3    4    8    8
[5,]    3    3    4    8    8

这些都是正确的结果。

我的问题是:&#34;有更好的方法来进行这种N-dim填充操作吗?

编辑1

感谢Frank,现在是N维padreplicate函数:

padreplicate <- function(a, padSize) {
    # Pad an array by replicating values.
    numDims <- length(padSize)
    idx <- vector("list", numDims)
    for (k in 1:numDims) {
        M <-  dim(a)[k]       # 32
        onesVector <-  ones(1, padSize[k])
        idx[[k]] <- c(onesVector, 1:M, M * onesVector)
    }
    do.call( `[`, c(list(a), idx)) 
}

编辑2

使用matrix代替我的函数ones。对不起。

padreplicate <- function(a, padSize) {
    # Pad an array by replicating values.
    numDims <- length(padSize)
    idx <- vector("list", numDims)
    for (k in 1:numDims) {
        M <-  dim(a)[k]       # 32
        onesVector <-  matrix(1, 1, padSize[k])
        idx[[k]] <- c(onesVector, 1:M, M * onesVector)
    }
    do.call( `[`, c(list(a), idx)) 
}

0 个答案:

没有答案