我正在寻找一种快速的方法来应用一些任意函数,这些函数对矢量(例如sum
)连续运行到连续K元素的子向量。
这是一个简单的例子,它应该非常清楚地说明我想要的东西:
v <- c(1, 2, 3, 4, 5, 6, 7, 8)
v2 <- myapply(v, sum, group_size=3) # v2 should be equal to c(6, 15, 15)
该函数应该尝试处理给定向量的group_size
个元素组,并将函数应用于每个组(将其视为另一个向量)。在这个例子中,矢量v2
如下获得:(1 + 2 + 3)= 6,(4 + 5 + 6)= 15,(7 + 8)= 15.在这种情况下,K没有完全划分N,所以最后一组的大小小于K.
如果有一个更好/更快的解决方案只有当N是K的倍数时才有效,我也会很感激。
答案 0 :(得分:7)
试试这个:
library(zoo)
rollapply(v, 3, by = 3, sum, partial = TRUE, align = "left")
## [1] 6 15 15
或
apply(matrix(c(v, rep(NA, 3 - length(v) %% 3)), 3), 2, sum, na.rm = TRUE)
## [1] 6 15 15
此外,在sum
的情况下,最后一个可以缩短为
colSums(matrix(c(v, rep(0, 3 - length(v) %% 3)), 3))
答案 1 :(得分:2)
正如@Chase在评论中所说,您可以创建自己的分组变量,然后使用它。将该过程包装成函数看起来像
myapply <- function(v, fun, group_size=1) {
unname(tapply(v, (seq_along(v)-1) %/% group_size, fun))
}
给出了结果
> myapply(v, sum, group_size=3)
[1] 6 15 15
请注意,这不要求v
的长度为group_size
的倍数。
答案 2 :(得分:0)
你也可以试试这个。即使您希望包含由by
控制的重叠间隔,并且作为奖励,返回每个值的推导间隔,这也很有效:
library (gtools)
v2 <- running(v, fun=sum, width=3, align="left", allow.fewer=TRUE, by=3)
v2
1:3 4:6 7:8
6 15 15