2012-01-15 182 views
1

这里可能是一个简单的问题..但我真的很苦恼,所以非常感谢帮助。如何将四维数组转换为三维数组子集的其中一个维的特定元素

我有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 

我渴望得到一些帮助!

回答

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矩阵。

+0

感谢您的回答!我虽然它会很简单,但我觉得我有点困惑! – 2012-01-15 17:28:30

+0

如果这确实回答了这个问题,那么通过点击复选标记就可以为其他读者提供帮助。 (目前我并不需要额外的积分,但是在使用这张支票之前,这个问题会一直显示为“未解答的问题”。) – 2012-01-15 17:59:00

0

除了@DWin的回答,我会推荐plyr软件包。该软件包提供了apply类似的功能。 apply的analgue是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的糟糕表现吗?

相关问题