3

我有以下深度和温度数据矩阵(855 行,2 列),并且想取每列中每 3 行的平均值。例如:

 [1,]  -6.7 18.91
 [2,]  -5.4 18.91
 [3,]  -4.0 18.59
 [4,]  -6.7 20.37
 [5,]  -6.7 20.05
 [6,]  -2.7 20.21
 [7,]  -4.0 21.03
 [8,]  -5.4 20.70
 [9,]  -4.0 20.87
[10,]  -2.7 21.37
[11,]  -2.7 21.37
[12,]  -2.7 21.37

mean(data[1:3,1])
mean(data[4:6,1])

对于整个矩阵。如果不为每 3 行的平均值手动编写代码,我怎样才能做到这一点?非常感谢任何想法或建议。

4

3 回答 3

6

使用rollapplyzoo 包中的功能。有关?rollapply更多详细信息,请参阅。

library(zoo)
rollapply(matrix[,1], width=3, mean, by=3)  

例子:

> set.seed(1)
> Data <- matrix(rnorm(30, 100, 50), ncol=2)  # some random data
> rollapply(Data[,1], width=3, mean, by=3)  
[1]  78.69268 118.40534 130.02559 126.60393  71.48317
> # you could check this out by doing some verification as in:
> mean(Data[1:3, 1])
[1] 78.69268
> mean(Data[4:6, 1])
[1] 118.4053
> mean(Data[7:9, 1]) # and so on ...
[1] 130.0256

如果您想要矩阵中所有列的平均值,则只需添加by.column=TRUE调用rollapply

> rollapply(Data, width=3, mean, by=3, by.colum=TRUE)
          [,1]      [,2]
[1,]  78.69268 114.71187
[2,] 118.40534 138.90166
[3,] 130.02559  81.12249
[4,] 126.60393 106.79836
[5,]  71.48317  74.48399
于 2013-02-20T18:53:23.530 回答
4

尝试使用tapplyapply

R > f <- rep(c(1:3), each = 3)
R > f
[1] 1 1 1 2 2 2 3 3 3
R > x <- matrix(1:27, 9, 3)
R > x
      [,1] [,2] [,3]
 [1,]    1   10   19
 [2,]    2   11   20
 [3,]    3   12   21
 [4,]    4   13   22
 [5,]    5   14   23
 [6,]    6   15   24
 [7,]    7   16   25
 [8,]    8   17   26
 [9,]    9   18   27
R > apply(x, 2, function(t) tapply(t, f, mean))
  [,1] [,2] [,3]
1    2   11   20
2    5   14   23
3    8   17   26
于 2013-02-20T18:56:29.220 回答
1

我真的很喜欢 'rollapply' 函数,因为它的语法与你想要做的非常匹配。但是,我想我会为后代贡献你将如何使用“plyr”包解决这个问题。

注意:您可以在一个语句中完成所有这些,但我已将其分解以使其更易于理解。

第 1 步:设置您的数据以具有排序变量。

data.plyr <- data.frame(test, group=floor((1:nrow(test)-1)/3)+1)

我刚刚添加了一个“组”列,它为每三列分配一个组号。默认情况下,两个矩阵列现在是“X1”和“X2”。

第 2 步:为每个组运行“colMeans”函数。

library(plyr)
ddply(data.plyr, .(group), colMeans)

对于这个特定的问题,我认为“plyr”包是次优的,但值得注意的是该方法以供将来参考。'apply' 系列和 'rollapply' 函数在数据的连续性和一致性方面效果最佳。在您需要更多灵活性的应用程序中,“plyr”系列函数在您的工具箱中很有用。

于 2013-02-20T19:20:41.407 回答