如何沿第 3 维滚动应用数组?
How to rollapply array along 3rd dimension?
假设我有数组:
> arr <- array(1, dim=c(3, 3, 3))
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 3
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
我想使用大小为 2 的滚动 window 计算移动平均值。这意味着我想计算数组的每个第 3 维的移动平均值,将它们乘以 2。在最后,我会有这样的东西:
> rollmeanThatWorksWithArrays(arr, k=2, margin=c(1, 2))
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
我可以使用 apply(arr, margin=c(1, 2), mean)
在第 3 个维度上做这个均值,但还不知道如何做滚动均值。也许 rollmean/rollapply 根本不支持它,我必须自己编写函数?
您可以手动执行以下操作(使用与您不同的数组):
library(zoo)
arr <- array(1:27, dim=c(3, 3, 3))
res <- do.call(rbind ,tapply(c(arr), rep(1:9, 3), function(x) rollmean(x, k = 2)))
array(c(res), dim = c(3, 3, 2))
, , 1
[,1] [,2] [,3]
[1,] 5.5 8.5 11.5
[2,] 6.5 9.5 12.5
[3,] 7.5 10.5 13.5
, , 2
[,1] [,2] [,3]
[1,] 14.5 17.5 20.5
[2,] 15.5 18.5 21.5
[3,] 16.5 19.5 22.5
假设输入 arr
与@RStudent 的回答相同。首先创建一个 data.frame ix
数组索引,它定义要取平均值的 arr
的子集。定义 Mean
以对数组列表取平均值。最后,对于每个 ix
列 k
形成 arr[,,k]
并将其转换为适合作为 Mean
输入的列表。取 Mean
并将结果简化为数组。
library(zoo)
w <- 2 # width
arr <- array(1:27, c(3, 3, 3))
n <- dim(arr)[3]
ix <- as.data.frame(t(rollapply(1:n, w, c)))
Mean <- function(L) Reduce("+", L) / length(L)
simplify2array(lapply(ix, function(ix) Mean(lapply(ix, function(k) arr[,,k]))))
给予:
, , V1
[,1] [,2] [,3]
[1,] 5.5 8.5 11.5
[2,] 6.5 9.5 12.5
[3,] 7.5 10.5 13.5
, , V2
[,1] [,2] [,3]
[1,] 14.5 17.5 20.5
[2,] 15.5 18.5 21.5
[3,] 16.5 19.5 22.5
假设我有数组:
> arr <- array(1, dim=c(3, 3, 3))
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 3
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
我想使用大小为 2 的滚动 window 计算移动平均值。这意味着我想计算数组的每个第 3 维的移动平均值,将它们乘以 2。在最后,我会有这样的东西:
> rollmeanThatWorksWithArrays(arr, k=2, margin=c(1, 2))
, , 1
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
, , 2
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
我可以使用 apply(arr, margin=c(1, 2), mean)
在第 3 个维度上做这个均值,但还不知道如何做滚动均值。也许 rollmean/rollapply 根本不支持它,我必须自己编写函数?
您可以手动执行以下操作(使用与您不同的数组):
library(zoo)
arr <- array(1:27, dim=c(3, 3, 3))
res <- do.call(rbind ,tapply(c(arr), rep(1:9, 3), function(x) rollmean(x, k = 2)))
array(c(res), dim = c(3, 3, 2))
, , 1
[,1] [,2] [,3]
[1,] 5.5 8.5 11.5
[2,] 6.5 9.5 12.5
[3,] 7.5 10.5 13.5
, , 2
[,1] [,2] [,3]
[1,] 14.5 17.5 20.5
[2,] 15.5 18.5 21.5
[3,] 16.5 19.5 22.5
假设输入 arr
与@RStudent 的回答相同。首先创建一个 data.frame ix
数组索引,它定义要取平均值的 arr
的子集。定义 Mean
以对数组列表取平均值。最后,对于每个 ix
列 k
形成 arr[,,k]
并将其转换为适合作为 Mean
输入的列表。取 Mean
并将结果简化为数组。
library(zoo)
w <- 2 # width
arr <- array(1:27, c(3, 3, 3))
n <- dim(arr)[3]
ix <- as.data.frame(t(rollapply(1:n, w, c)))
Mean <- function(L) Reduce("+", L) / length(L)
simplify2array(lapply(ix, function(ix) Mean(lapply(ix, function(k) arr[,,k]))))
给予:
, , V1
[,1] [,2] [,3]
[1,] 5.5 8.5 11.5
[2,] 6.5 9.5 12.5
[3,] 7.5 10.5 13.5
, , V2
[,1] [,2] [,3]
[1,] 14.5 17.5 20.5
[2,] 15.5 18.5 21.5
[3,] 16.5 19.5 22.5