如何将4d数组转换为其中一个维度的特定元素的3d数组子集

时间:2012-01-15 16:44:19

标签: r multidimensional-array average

这可能是一个简单的问题..但我真的很挣扎,所以非常感谢帮助。

我有4d数据,我希望转换成3d数据。数据具有以下属性:

lon <- 1:96  
lat <- 1:73  
lev <- 1:60  
tme <- 1:12

data <- array(runif(96*73*60*12), 
              dim=c(96,73,60,12) ) # fill with random test values  

我想要做的是计算前几个等级的平均值(比如1:6)。新数据的格式如下:

new.data <- array(96*73*12), dim=c(96,73,12) ) # again just test data  

但是会包含前5个级别数据的平均值。目前,我能够使其工作的唯一方法是编写一个相当低效的循环,它提取前5个级别中的每个级别,并将这些级别的总和除以5得到平均值。

我试过了:

new.data <- apply(data, c(1,2,4), mean)  

这很好地给了我所有垂直水平的平均值但却无法理解如何将第三维子集化以获得平均只有几个!例如

new.data <- apply(data, c(1,2,3[1:5],4), mean) # which returns   
  Error in ds[-MARGIN] : only 0's may be mixed with negative subscripts

我迫切需要一些帮助!

2 个答案:

答案 0 :(得分:3)

带有索引的

apply(正确使用“[”)对于第三维的前六个级别的mean应该足够了,如果我理解你的术语:

> str(apply(data[,,1:6,] , c(1,2,4), FUN=mean) )
 num [1:96, 1:73, 1:12] 0.327 0.717 0.611 0.388 0.47 ...

这将返回一个96 x 73乘12的矩阵。

答案 1 :(得分:0)

除了@DWin的答案,我还会推荐plyr包。该软件包提供了类似apply的功能。 apply的分析是plyr函数aaply。 plyr函数的前两个字母指定输入和输出类型,在本例中为aaarrayarray

> system.time(str(apply(data[,,1:6,], c(1,2,4), mean)))
 num [1:96, 1:73, 1:12] 0.389 0.157 0.437 0.703 0.61 ...
   user  system elapsed 
  2.180   0.004   2.184 
> Library(plyr)
> system.time(str(aaply(data[,,1:6,], c(1,2,4), mean)))
 num [1:96, 1:73, 1:12] 0.389 0.157 0.437 0.703 0.61 ...
 - attr(*, "dimnames")=List of 3
  ..$ X1: chr [1:96] "1" "2" "3" "4" ...
  ..$ X2: chr [1:73] "1" "2" "3" "4" ...
  ..$ X3: chr [1:12] "1" "2" "3" "4" ...
   user  system elapsed 
 40.243   0.016  40.262 

在此示例中,它比apply慢,但有一些优点。这些包支持并行处理,它还支持将结果输出到data.framelist(很适合使用ggplot2进行绘图),并且它可以显示进度条(适用于长时间运行的进程) )。虽然在这种情况下我仍然会因为表现而申请。

有关plyr包的更多信息,请参阅this paper。也许有人可以评论此示例中aaply的糟糕表现?