可以在r

时间:2016-12-01 12:00:29

标签: r

可以在3维数组上使用聚合来查找R中唯一天数的平均值吗?

例如,考虑我有一个具有三个维度的数据集,比如经度,纬度和时间,但其中一个时间是重复的:

dtime <- seq(from=as.POSIXct("2012-01-01", tz="UTC"),
             to=as.POSIXct("2012-01-10", tz="UTC"),
             by="day")
dtime[10] <- dtime[9]
a <- array(c(runif(9), runif(9)), c(3,3,10))

对于单个lat / lon单元,我可以计算所有唯一时间的平均值:

dat2 <- aggregate(a[1,1,], by = list(dtime), mean)
# quick check
dat2b <- dat2[,2]
dat2b[length(dat2b)] == (a[1,1,10]+a[1,1,9])/2

但是如何为所有纬度/经度组合执行此操作,即将其应用于整个数据?具体而言,整个数据的dat2的维度为

> dim(dat2)
[1]  3  3 9

而不是具有

的原始数据
> dim(a)
[1]  3  3 10

因为最后两天是重复的。

任何建议表示赞赏。

2 个答案:

答案 0 :(得分:0)

由于你已经拥有一个数组,apply可能就是这样。这将获取一个数组并沿您指定的边距应用某些函数。

在&#34; z&#34;中应用均值数组的(时间)维度:

apply(a, c(1,3), mean)
          [,1]      [,2]      [,3]
[1,] 0.3139773 0.4530565 0.4233957
[2,] 0.6579453 0.8921744 0.2593869
[3,] 0.5771248 0.4663132 0.4664523

在计算中省略第十个(重复)矩阵,只需子集:

apply(a[,,1:9], c(1,2), mean)
          [,1]      [,2]      [,3]
[1,] 0.2917246 0.4719813 0.3774068
[2,] 0.6539847 0.8887012 0.2564051
[3,] 0.5806970 0.4856463 0.4886335

作为一项检查,请注意将mean应用于第一行中元素的输出,第一列对应于矩阵中的相应元素:

mean(a[1,1,1:9])
[1] 0.2917246

如果不是忽略第十个矩阵,而是想要计算第9个和第10个矩阵的平均值,然后计算9个维度的平均值,可以使用apply两次,同时使用abind

library abind
apply(abind(a[,,1:8], apply(a[,,9:10], c(1,2), mean)), c(1,2), mean)
          [,1]      [,2]      [,3]
[1,] 0.3139773 0.4530565 0.4233957
[2,] 0.6579453 0.8921744 0.2593869
[3,] 0.5771248 0.4663132 0.4664523

数据

set.seed(1234)
 a <- array(c(runif(9), runif(9)), c(3,3,10))

答案 1 :(得分:0)

我建议使用reshape2功能meltacast采用不同的方法。我认为这是因为我编程思考长格式数据,你会有一个带有变量Lon,Lat,Time和Value的数据框,这使得许多其他操作更容易。为此...

library(reshape2)
library(dplyr)

out = apply(a,3, function(x){
  d = melt(x)
  colnames(d) = c("Lat","Lon","Value")
  as.data.frame(d)
} )

df = do.call(rbind,out)
df$time = rep(dtime,each = 9)

给我一​​个二维数据框,包含与三维数组相同的信息。我不确定你的行或列是否是Lat,所以我选了一个,显然你知道答案,所以选择相应的。

聚合是没有问题的,因为我们的格式很好

res = aggregate(Value~Lat + Lon + time, data = df, mean)

检查第一个Lon,Lat对是否正确的情况:(此处使用可选的dplyr,显然可以使用[获取子集)

res %>% filter(Lat == 1, Lon == 1) %>% select(Value) == dat2[,2]

如果你真的希望你的最终结果是(3,3,9)的三维数组,那么你可以使用acast

acast(res,Lat~Lon~time)