【问题标题】:Applying function to consecutive subvectors of equal size将函数应用于大小相等的连续子向量
【发布时间】:2011-09-14 17:58:23
【问题描述】:

我正在寻找一种很好且快速的方法来将一些对向量进行操作的任意函数(例如 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 的倍数时才有效,我也将不胜感激。

【问题讨论】:

  • 提示 - 您可以先创建分组变量,然后使用任何一个应用/聚合函数按组计算统计信息。

标签: r split grouping apply


【解决方案1】:

试试这个:

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))

【讨论】:

    【解决方案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 的倍数。

    【讨论】:

    • 快一点的是:unlist(tapply(v, (seq_along(v)-1) %/% group_size, fun,simplify=FALSE),use.names=FALSE)
    【解决方案3】:

    你也可以试试这个。即使您想要包含由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 
    

    【讨论】:

      猜你喜欢
      • 2015-01-16
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多