这可能是一个简单的问题..但我真的很挣扎,所以非常感谢帮助。
我有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
我迫切需要一些帮助!
答案 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函数的前两个字母指定输入和输出类型,在本例中为aa
,array
和array
。
> 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.frame
或list
(很适合使用ggplot2
进行绘图),并且它可以显示进度条(适用于长时间运行的进程) )。虽然在这种情况下我仍然会因为表现而申请。
有关plyr包的更多信息,请参阅this paper。也许有人可以评论此示例中aaply
的糟糕表现?