替换数组n个维中的第一个维的值

时间:2019-01-02 16:52:49

标签: r multidimensional-array

编辑:我已经简化了示例和@jdorbes注释之后的功能。希望这可以改善帖子。

我有一系列的N维数组,我需要沿着它们的第一维“旋转”(例如,在2d矩阵中,在列的第一半和第二半之间相互切换)。 例如,考虑3D情况,我可以将数组定义为:

field <- array(1:32, c(4, 4, 2))

我开发了一个非常基本且与尺寸相关的功能,可以实现目标。当然,也可以使用headtail进行相同的操作,但是我发现这是更快的方法:

rotate.test <- function(field) {
  xxx <- field
  dims <- length(dim(xxx))
  if (dims == 2) { # for x,y data
      ll <- length(field[, 1])
      field[(ll * 0.5 + 1  ):ll, ] <- xxx[1:(ll * 0.5), ]
      field[1:(ll * 0.5), ] <- xxx[(ll * 0.5  + 1):ll, ]
  }
  if (dims == 3) { # for x,y,t data
      ll <- length(field[, 1, 1]) 
      field[(ll * 0.5 + 1 ):ll, , ] <- xxx[1:(ll * 0.5), , ]
      field[1:(ll * 0.5), , ] <- xxx[(ll * 0.5 + 1):ll, , ]
  } 
    return(field)
}

结果显示为:

> rotate.test(field)
, , 1

     [,1] [,2] [,3] [,4]
[1,]    3    7   11   15
[2,]    4    8   12   16
[3,]    1    5    9   13
[4,]    2    6   10   14

, , 2

     [,1] [,2] [,3] [,4]
[1,]   19   23   27   31
[2,]   20   24   28   32
[3,]   17   21   25   29
[4,]   18   22   26   30

这可以进一步推广到N维数据,但是我想您会发现它非常笨拙。 在这篇Select along one of n dimensions in array的帖子之后,我发现可以对其进行概括,向do.call函数引入非常有用的调用:

array_indexing <- function(field, dim, value, drop = FALSE) {
  indices <- rep(list(bquote()), length(dim(field)))
  indices[[dim]] <- value
  out <- do.call("[",c(list(field), indices, list(drop = drop)))
  return(out)
}

然后使用abind

rotate.evo <- function(field) {
 require("abind")
 xdim <- 1
 ll <- dim(field)[xdim]
 firstchunk <- array_indexing(field, xdim, (ll * 0.5 + 1):ll)
 secondchunk <- array_indexing(field, xdim, 1:(ll * 0.5))
 out <- abind(firstchunk, secondchunk, along = 1)
 return(out)
}

但是,由于调用了rbenchmark而不是简单的索引替换,基准测试(用abind完成)很糟糕。

                test replications elapsed relative user.self sys.self
2  rotate.evo(field)         1000   0.547     6.36     0.542    0.005
1 rotate.test(field)         1000   0.086     1.00     0.069    0.016
  user.child sys.child
2          0         0
1          0         0

这是我的问题:有没有办法像array_indexing函数那样概括索引替换?换句话说,是否有任何方法可以快速而可靠地执行此切换,而无需为每个维度编写临时案例?我试图找出的是R中存在的一种方法,用于沿定义的维度概括替换某些数组索引。

我知道这听起来像是一个奇怪的请求,但是如果我可以避免加载额外的程序包,那就太好了。该代码包含在一个在线工具中,该工具应该更轻巧(实际上,我也想摆脱绑定!)

感谢您的任何提示,请询问我的解释是否不完整。 最好, 保罗

0 个答案:

没有答案