rollapply 用于二维数组 (R)
rollapply for two-dimensional arrays (R)
有一些我想做的事情,我相信 rollapply
应该很容易实现,但我遇到了一些麻烦。
对于简单的向量,我们有
> a <- c(1:10)
> a
[1] 1 2 3 4 5 6 7 8 9 10
> rollapply(a, 2, mean)
[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
这是应该的。但是更高维度会出现问题
> b <- array(c(1:6), c(2,3))
> b
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> rollapply(b, 2, mean)
[,1] [,2] [,3]
[1,] 1.5 3.5 5.5
如果我 想要 应用于列,这很好 - 但肯定还必须有一些方法来代替应用于行并获得
[,1] [,2]
[1,] 2 4
[2,] 3 5
据我所知,rollapply
函数无法执行此操作。
我们可以简单地使用 apply
和 MARGIN = 1
来遍历行并应用 rollapply
。 MARGIN
也可以针对更高的维度进行调整,即它是更通用的解决方案
t(apply(b, 1, function(x) rollapply(x, 2, mean)))
-输出
# [,1] [,2]
#[1,] 2 4
#[2,] 3 5
或使用 dapply
来自 collapse
library(collapse)
dapply(b, FUN = function(x) rollapply(x, 2, fmean), MARGIN = 1)
您可以简单地转置您的矩阵,然后将其转回:
t(rollapply(t(b), 2, mean))
[,1] [,2]
[1,] 2 4
[2,] 3 5
基本 R 选项
> do.call(`+`, lapply(c(1, ncol(b)), function(k) b[, -k])) / 2
[,1] [,2]
[1,] 2 4
[2,] 3 5
跟进
如果您想使用基本 R 实现并扩展到一般情况,即超过 2 个,那么您可以尝试下面的代码,其中定义了一个函数 f
:
f <- function(b, m) {
apply(
simplify2array(
lapply(
data.frame(t(embed(seq(ncol(b)), m))[m:1, ]),
function(k) b[, k]
)
), 1:2, mean
)
}
你会看到
> f(array(c(1:6), c(2, 3)), 2)
[,1] [,2]
[1,] 2 4
[2,] 3 5
> f(array(c(1:12), c(2, 6)), 4)
[,1] [,2] [,3] [,4]
[1,] 3 5 7 9
[2,] 4 6 8 10
有一些我想做的事情,我相信 rollapply
应该很容易实现,但我遇到了一些麻烦。
对于简单的向量,我们有
> a <- c(1:10)
> a
[1] 1 2 3 4 5 6 7 8 9 10
> rollapply(a, 2, mean)
[1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
这是应该的。但是更高维度会出现问题
> b <- array(c(1:6), c(2,3))
> b
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> rollapply(b, 2, mean)
[,1] [,2] [,3]
[1,] 1.5 3.5 5.5
如果我 想要 应用于列,这很好 - 但肯定还必须有一些方法来代替应用于行并获得
[,1] [,2]
[1,] 2 4
[2,] 3 5
据我所知,rollapply
函数无法执行此操作。
我们可以简单地使用 apply
和 MARGIN = 1
来遍历行并应用 rollapply
。 MARGIN
也可以针对更高的维度进行调整,即它是更通用的解决方案
t(apply(b, 1, function(x) rollapply(x, 2, mean)))
-输出
# [,1] [,2]
#[1,] 2 4
#[2,] 3 5
或使用 dapply
来自 collapse
library(collapse)
dapply(b, FUN = function(x) rollapply(x, 2, fmean), MARGIN = 1)
您可以简单地转置您的矩阵,然后将其转回:
t(rollapply(t(b), 2, mean))
[,1] [,2]
[1,] 2 4
[2,] 3 5
基本 R 选项
> do.call(`+`, lapply(c(1, ncol(b)), function(k) b[, -k])) / 2
[,1] [,2]
[1,] 2 4
[2,] 3 5
跟进
如果您想使用基本 R 实现并扩展到一般情况,即超过 2 个,那么您可以尝试下面的代码,其中定义了一个函数 f
:
f <- function(b, m) {
apply(
simplify2array(
lapply(
data.frame(t(embed(seq(ncol(b)), m))[m:1, ]),
function(k) b[, k]
)
), 1:2, mean
)
}
你会看到
> f(array(c(1:6), c(2, 3)), 2)
[,1] [,2]
[1,] 2 4
[2,] 3 5
> f(array(c(1:12), c(2, 6)), 4)
[,1] [,2] [,3] [,4]
[1,] 3 5 7 9
[2,] 4 6 8 10