【问题标题】:Cumulative average with conditions to update有条件更新的累积平均值
【发布时间】:2019-12-21 16:17:44
【问题描述】:

我有一个纵向记录的变量 (Var.1)。我想随着时间的推移计算累积平均值(或“正常”)变量。更重要的是,我只想在 Var.1 满足条件时更新累积平均值,在这种情况下,它是先前正常值的 >70%。如果满足,则应更新,如果不满足,则应结转先前的值。我一直在寻找矢量化解决方案,但不确定这是否可行。

我的示例数据如下。我已经输入了排除第 5 个条目 (50) 后的正常值,因为它不满足 >70% 规则。

library(tibble)
Sample.GT = tibble(Var.1 = c(80, 80,90,90,50,80,70, 80,80,80),
                   Normal = c(80, 80,83.33,85,85,84,81.67,81.43,81.25,81.11))

首选 Dplyr 或 data.table 解决方案。我希望通过跨大型数据集的组来实现这一点,因此快速解决方案是理想的。

【问题讨论】:

    标签: r function dplyr data.table


    【解决方案1】:

    data.table 中一种可能的递归方法:

    n <- 1
    cs <- GT$Var.1[1L]
    GT[1L, cm := cs]
    GT[-1L, cm := {
        if (Var.1 > 0.7*cs/n) {
            cs <- cs + Var.1
            n <- n + 1
        }
        cs / n
    }, seq_len(GT[,.N])[-1L]]
    

    或使用Rcpp 会更快:

    library(Rcpp)
    calcNorm <- cppFunction('
    NumericVector calcNorm(NumericVector v) {
        int sz = v.size();
        double n = 1.0, cs = v[0];
        NumericVector ret(sz);
        ret[0] = cs;
    
        for (int i = 1; i < sz; i++) {
            if (v[i] > 0.7*cs/n) {
                cs = cs + v[i];
                n = n + 1.0;
            }
            ret[i] = cs / n;   
        }
        return(ret);
    }
    ')
    GT[, newNormal := calcNorm(Var.1)]
    

    输出:

        Var.1 Normal       cm
     1:    80  80.00 80.00000
     2:    80  80.00 80.00000
     3:    90  83.33 83.33333
     4:    90  85.00 85.00000
     5:    50  85.00 85.00000
     6:    80  84.00 84.00000
     7:    70  81.67 81.66667
     8:    80  81.43 81.42857
     9:    80  81.25 81.25000
    10:    80  81.11 81.11111
    

    数据:

    library(data.table)
    GT = data.table(Var.1 = c(80, 80,90,90,50,80,70, 80,80,80),
        Normal = c(80, 80,83.33,85,85,84,81.67,81.43,81.25,81.11))
    

    感谢 sindri_baldur 的评论编辑

    【讨论】:

    • 不是有bug吗? x &lt;- c(10, 7, 8);calcNorm(x) 在不正确的时候更新第二个累积平均值?
    • 嗯,可能是 v[i] > 0.7*cs/n。没有要检查的补偿
    猜你喜欢
    • 2016-05-28
    • 2015-11-19
    • 1970-01-01
    • 2016-07-11
    • 2015-12-10
    • 2012-06-19
    • 1970-01-01
    相关资源
    最近更新 更多