【问题标题】:R: Apply to slices of an array and return an arrayR:应用于数组的切片并返回一个数组
【发布时间】:2017-08-25 03:57:47
【问题描述】:

我想找到跨数组切片应用函数的最简单方法,其中函数的每个应用都返回一个矩阵,并接收一个合理的数组对象作为最终答案。

我觉得应该有一个简单的方法来使用 apply 函数来做到这一点,但我觉得我需要一个 simplify = 'array' 选项,这将非常方便。我得到的最接近的是:

dims = c(2,3,10,4,5)
arr = array(runif(prod(dims)),dim = dims, dimnames = 
          list(
            paste0('a',1:dims[1]),
            paste0('b',1:dims[2]),
            paste0('c',1:dims[3]),
            paste0('d',1:dims[4]),
            paste0('e',1:dims[5])
          ))

result = apply(arr, c(4,5), function(x) apply(x, c(3), function(y) (y - y[,1])^2 ) )

result 应该是一个维度为 c(2,3,10,4,5) 或其某种排列的数组。

我可以通过在result 上使用适当的尺寸调用as.array 来获得正确的形式,但应该有一种更简单的方法可以自动保留dimnames

【问题讨论】:

  • 要使用apply,请指定要保留的边距:apply(arr, 2:5, function(x){mean(x^2)})
  • @alistaire - 这绝对应该是一个答案 - 它非常简单。 apply(arr^2, 2:5, mean) 甚至可以在这种特殊情况下工作。
  • 对不起,我举了一个不好的例子。我将更正示例以符合问题的措辞和实际目标...

标签: arrays r apply


【解决方案1】:

这可以通过plyr 包中的aaply 函数来完成。这是这个包中的几个应用函数之一,其中的命名约定是aaply 中的aa 代表数组到数组。

dims = c(2,3,10,4,5)
arr = array(runif(prod(dims)),dim = dims, dimnames = 
          list(
            paste0('a',1:dims[1]),
            paste0('b',1:dims[2]),
            paste0('c',1:dims[3]),
            paste0('d',1:dims[4]),
            paste0('e',1:dims[5])
          ))

aresult = (aaply(arr, c(4,5), function(x) aaply(x, c(3), function(y) (y - y[,1])^2 ) ) )
result = aperm(abind(aresult), c(4,5,3,1,2))

【讨论】:

    【解决方案2】:

    要使用apply 遍历多维数组,请指定要保留的边距。更容易在二维中可视化:

    m <- matrix(1, 2, 3)
    
    m
    #>      [,1] [,2] [,3]
    #> [1,]    1    1    1
    #> [2,]    1    1    1
    
    apply(m, 1, sum)
    #> [1] 3 3
    

    ——遍历行保持该维度,并折叠未提及的第一列。那么,对于更复杂的数组,

    res <- apply(arr, 2:5, function(x){mean(x^2)})
    # or even just apply(arr^2, 2:5, mean) (h/t @thelatemail)
    
    str(res)
    #>  num [1:2, 1:3, 1:4, 1:5] 0.313 0.215 0.32 0.29 0.288 ...
    #>  - attr(*, "dimnames")=List of 4
    #>   ..$ : chr [1:2] "b1" "b2"
    #>   ..$ : chr [1:3] "c1" "c2" "c3"
    #>   ..$ : chr [1:4] "d1" "d2" "d3" "d4"
    #>   ..$ : chr [1:5] "e1" "e2" "e3" "e4" ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 2019-12-16
      • 2018-04-22
      • 2012-09-17
      • 2012-11-10
      • 2014-04-22
      相关资源
      最近更新 更多