【问题标题】:Create a new column by applying a Reduce function over rows of a dataframe in R通过在 R 中的数据框行上应用 Reduce 函数来创建新列
【发布时间】:2016-01-23 01:32:53
【问题描述】:

我有一个包含 ID、日期和观察到的回报的数据框。可以比喻成这样:

df <- data.frame(
  ID = gl(3, 10, labels = c("A", "B", "C")), 
  Date = factor(rep(2006, 2015, 3)), 
  lr = runif(30, -0.01, 0.01))

现在我想使用以下函数来查找每个 ID 的指数移动平均值的向量,并将它们作为新列添加到我的原始数据框中:

Emean<-function(x){
    ema <- function(a,b) {lambda*a+(1-lambda)*b}
    Reduce(ema, x, accumulate=T)
}

所以我希望生成的数据框包含 ID、Date、lr 和 mlr 列。最后一列(mlr)将使用上述函数计算;和(对不起,符号松散!)但这是公式:

mlr_t=lambda*mlr_t-1 + (1-lambda)*lr_t

'_t' 表示时间。

现在正如我所说,我想将我的函数应用于按 ID 分组的行,并将结果作为列添加到此数据框中。 'Reduce' 的输出不能直接添加到该数据帧中,我必须分几个步骤操作它,这在 R 中非常耗时。

我需要一个计算效率高的解决方案来完成我所说的。在实际数据集中,每个 ID 有 +100K 个 ID 和 +250 个日期。

【问题讨论】:

    标签: r dataframe apply reduce


    【解决方案1】:

    作为

    mlr_0 = 0
    mlr_1 = 0 + (1-lambda)*lr_1
    mlr_2 = lambda * mlr_1 + (1-lambda)*lr_2
          = lambda * (1-lambda) * lr_1 + (1-lambda)*lr_2
    mlr_3 = lambda * mlr_2 + (1-lambda)*lr_3
          = lambda^2 * (1-lambda) * lr_1 + lambda * (1-lambda) * lr_2 + (1-lambda)*lr_3
    ...
    mlr_t = lambda^(t-1) * (1-lambda) * lr_1 + lambda^(t-2) * (1-lambda) * lr_2 + ...
          = \Sum_{i=1}^{t} lambda^(t-i) * (1-lambda)*lr_i
    

    你可以做这样的事情(使用data.table

    setDT(df)
    lambda <- 0.5
    # This calculates the lambda^(t-i)
    l <- function(i, lambda){ lambda^(i-seq_len(i)) }
    
    # This calculates multiplies element wise and sums up the mlr_3
    my_fun <- function(x, lr, lambda){
      sum((1-lambda) * c(0,lr)[1:x] * l(x, lambda))}
    
    # Apply both function to the vector
    df[, vapply(seq_len(.N), my_fun, numeric(1), lr, lambda)  ,by = ID]
    

    结果(set.seed(42)

        ID        V1
     1:  A 0.0000000
     2:  A 0.4574030
     3:  A 0.6972392
     4:  A 0.4916894
     5:  A 0.6610685
     6:  A 0.6514070
     7:  A 0.5852515
     8:  A 0.6609199
     9:  A 0.3977932
    10:  A 0.5273928
    11:  B 0.0000000
    12:  B 0.2288709
    ...
    

    【讨论】:

    • 最初我想使用我的 Emean 函数将计算得到的 EMA 向量作为我的数据框中的一个新列。但我认为这里提出的答案有效。谢谢!
    猜你喜欢
    • 2016-06-15
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2021-12-12
    • 2017-07-29
    • 2020-05-09
    • 2020-06-20
    • 2022-08-13
    相关资源
    最近更新 更多