将函数应用于具有分组变量的多维数组

时间:2013-04-21 20:29:42

标签: r

我认为这是一个简单的问题,但我找不到合适的答案。我有一个多维数组v[x,y,z],我想使用分组变量(组)沿着 z 维度向数组应用一个函数。这是一个例子(在R中):

v<-1:81
dim(v)<-c(3,3,9)
group<-c('a','a','a','b','b','b','c','c','c')

鉴于分组变量有3个级别( a b c ),结果( out >)我正在寻找的是一个尺寸为3x3x3的数组。我可以使用以下代码获取以上示例:

out1<-apply(v[,,c(1:3)],c(1,2),sum)
out2<-apply(v[,,c(4:6)],c(1,2),sum)
out3<-apply(v[,,c(7:9)],c(1,2),sum)

library(abind)
out<-abind(out1, out2, out3, along=3) 

我的问题是,是否有一种获得上述结果的一般方法,可以应用于大维数组和长分组向量。

3 个答案:

答案 0 :(得分:6)

易:

out <- apply(v, c(1, 2), by, group, sum)

但要以完全相同的顺序获取数据:

out <- aperm(apply(v, c(1, 2), by, group, sum), c(2, 3, 1))

答案 1 :(得分:5)

使用包栅格可能更适合您的需要。它有一些优化的代码用于处理遥感数据,负责处理块。考虑这个例子:

## Make 12 rasters, maybe one for each month of the year
for( i in seq(12) ){
    assign( paste0( "r" , i ) , raster( matrix(runif(1e3) , nrow = 1e2 ) ) )
}

## Create a raster stack from these
rS <- stack( mget( paste0("r",1:12) , envir = .GlobalEnv ) )

## Use calc to get mean, using by to group by a variable
## In this example I use the vector (1,1,1,2,2,2,3,3,3,4,4,4)
## meaning I get means for the first 3 rasters, then the next 3 etc
## So I get a mean for each quarter
rMean <- calc( rS , fun = function(x){ by(x , c( rep( 1:4 , each=3 ) ) , mean ) }  )

返回一个有4层的栅格砖(每个季度一个均值):

class       : RasterBrick 
dimensions  : 100, 10, 1000, 4  (nrow, ncol, ncell, nlayers)
resolution  : 0.1, 0.01  (x, y)
extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
coord. ref. : NA 
data source : in memory
names       :         X1,         X2,         X3,         X4 
min values  : 0.02096586, 0.04015260, 0.04704145, 0.05884161 
max values  :  0.9727491,  0.9303025,  0.9804486,  0.9934670

我希望您能够根据您的数据进行调整。

答案 2 :(得分:2)

如果您的数据格式化为数据框,这会容易得多:

library(plyr)
vd <- adply(v, 1:3)
head(vd)

  X1 X2 X3 V1
1  1  1  1  1
2  2  1  1  2
3  3  1  1  3
4  1  2  1  4
5  2  2  1  5
6  3  2  1  6

然后,您可以简单地附加您的分组......

vd$group <- rep(group, rep(3 * 3, length(group)))

...并根据此分组进行拆分:

daply(vd, .(group), function(df) { ... } )

将为每个组调用一次匿名函数{ ... },其中df包含与该组对应的子数据框。在这里,您可以使用类似的机器将数据重新组合并汇总到矩阵中。该函数应返回一个3x3x1维的数组,这些数组将由daply连接起来以形成所需的结果。