简体   繁体   English

在没有显式 for 循环的情况下对组和行应用递归函数

[英]apply a recursive function over groups and rows without explicit for loop

Apologies for the title;为标题道歉; I don't know how to word this problem, so I'll go by example and hopefully provide a reprex.我不知道如何描述这个问题,所以我会举个例子,希望能提供一个reprex。

Let's say I have the following data frame:假设我有以下数据框:

tmp <- data.frame(Campaign = rep(c("Toy", "Clothing"), each = 10), 
                  CPC = rep(c(6.40, 10.30), each = 10), 
                  CompoundGrowth = rep(c(0.005, 0.0123), each = 10), 
                  Month = rep(seq(as.Date("2013-01-01"), 
                                  as.Date("2013-01-01") + months(9), by = "month"), 2)
                 )
OUT:
-----------------------------------------------------------
    Campaign  CPC CompoundGrowth      Month
1       Toy  6.4         0.0050 2013-01-01
2       Toy  6.4         0.0050 2013-02-01
3       Toy  6.4         0.0050 2013-03-01
4       Toy  6.4         0.0050 2013-04-01
5       Toy  6.4         0.0050 2013-05-01
6       Toy  6.4         0.0050 2013-06-01
7       Toy  6.4         0.0050 2013-07-01
8       Toy  6.4         0.0050 2013-08-01
9       Toy  6.4         0.0050 2013-09-01
10      Toy  6.4         0.0050 2013-10-01
11 Clothing 10.3         0.0123 2013-01-01
12 Clothing 10.3         0.0123 2013-02-01
13 Clothing 10.3         0.0123 2013-03-01
14 Clothing 10.3         0.0123 2013-04-01
15 Clothing 10.3         0.0123 2013-05-01
16 Clothing 10.3         0.0123 2013-06-01
17 Clothing 10.3         0.0123 2013-07-01
18 Clothing 10.3         0.0123 2013-08-01
19 Clothing 10.3         0.0123 2013-09-01
20 Clothing 10.3         0.0123 2013-10-01

I want to add a column ProjCPC我想添加一个列 ProjCPC

ProjCPC = ProjCPC + ProjCPC * CompoundGrowth 

where the first row would be第一行在哪里

CPC + CPC * CompoundGrowth. 

In other words, a recursive function where换句话说,一个递归函数,其中

f(x) = f(x)*c + f(x).

I really wanted this to work我真的想让这个工作

projection_func <- function(current_projection, cpc_growth){
    current_projection = current_projection * cpc_growth + current_projection
    return(current_projection)
}

tmp %>% dplyr::group_by(Campaign, Month) %>% 
    dplyr::rowwise() %>%
    mutate(CPC = ifelse(is.na(lag(CPC)), projection_func(CPC, CompoundGrowth),
                                      projection_func(lag(CPC), CompoundGrowth)
    )
)

But it only does the first calculation:但它只做第一次计算:

   Campaign   CPC CompoundGrowth Month     
   <fct>    <dbl>          <dbl> <date>    
 1 Toy       6.43         0.005  2013-01-01
 2 Toy       6.43         0.005  2013-02-01
 3 Toy       6.43         0.005  2013-03-01
 4 Toy       6.43         0.005  2013-04-01
 5 Toy       6.43         0.005  2013-05-01
 6 Toy       6.43         0.005  2013-06-01
 7 Toy       6.43         0.005  2013-07-01
 8 Toy       6.43         0.005  2013-08-01
 9 Toy       6.43         0.005  2013-09-01
10 Toy       6.43         0.005  2013-10-01
11 Clothing 10.4          0.0123 2013-01-01
12 Clothing 10.4          0.0123 2013-02-01
13 Clothing 10.4          0.0123 2013-03-01
14 Clothing 10.4          0.0123 2013-04-01
15 Clothing 10.4          0.0123 2013-05-01
16 Clothing 10.4          0.0123 2013-06-01
17 Clothing 10.4          0.0123 2013-07-01
18 Clothing 10.4          0.0123 2013-08-01
19 Clothing 10.4          0.0123 2013-09-01
20 Clothing 10.4          0.0123 2013-10-01

Output I am expecting:我期待的输出:

   Campaign  expected CompoundGrowth      Month
1       Toy  6.432000         0.0050 2013-01-01
2       Toy  6.464160         0.0050 2013-02-01
3       Toy  6.496481         0.0050 2013-03-01
4       Toy  6.528963         0.0050 2013-04-01
5       Toy  6.561608         0.0050 2013-05-01
6       Toy  6.594416         0.0050 2013-06-01
7       Toy  6.627388         0.0050 2013-07-01
8       Toy  6.660525         0.0050 2013-08-01
9       Toy  6.693828         0.0050 2013-09-01
10      Toy  6.727297         0.0050 2013-10-01
11 Clothing 10.426690         0.0123 2013-01-01
12 Clothing 10.554938         0.0123 2013-02-01
13 Clothing 10.684764         0.0123 2013-03-01
14 Clothing 10.816187         0.0123 2013-04-01
15 Clothing 10.949226         0.0123 2013-05-01
16 Clothing 11.083901         0.0123 2013-06-01
17 Clothing 11.220233         0.0123 2013-07-01
18 Clothing 11.358242         0.0123 2013-08-01
19 Clothing 11.497948         0.0123 2013-09-01
20 Clothing 11.639373         0.0123 2013-10-01

Code used to produce the above (trying to avoid this kind of solution):用于产生上述代码(试图避免这种解决方案):

for(i in seq_along(tmp$Campaign)){
    if(i%%10 %in% c(1,10)){
        starter = projection_func(tmp$CPC[i], tmp$CompoundGrowth[i])
    }
    else{
        starter = projection_func(starter, tmp$CompoundGrowth[i])
    }
    tmp$expected[i] <- starter
}

Since every calculation is dependent on the outcome of previous calculation, you can use accumalate from purrr .由于每个计算都依赖于先前计算的结果,因此您可以使用accumalatepurrr

library(dplyr)

tmp %>%
  group_by(Campaign) %>%
  mutate(ProjCPC = purrr::accumulate(CompoundGrowth, projection_func, 
                  .init = first(CPC))[-1]) 

#   Campaign  CPC CompoundGrowth      Month   ProjCPC
#1       Toy  6.4         0.0050 2013-01-01  6.432000
#2       Toy  6.4         0.0050 2013-02-01  6.464160
#3       Toy  6.4         0.0050 2013-03-01  6.496481
#4       Toy  6.4         0.0050 2013-04-01  6.528963
#5       Toy  6.4         0.0050 2013-05-01  6.561608
#6       Toy  6.4         0.0050 2013-06-01  6.594416
#7       Toy  6.4         0.0050 2013-07-01  6.627388
#8       Toy  6.4         0.0050 2013-08-01  6.660525
#9       Toy  6.4         0.0050 2013-09-01  6.693828
#10      Toy  6.4         0.0050 2013-10-01  6.727297
#11 Clothing 10.3         0.0123 2013-01-01 10.426690
#12 Clothing 10.3         0.0123 2013-02-01 10.554938
#13 Clothing 10.3         0.0123 2013-03-01 10.684764
#14 Clothing 10.3         0.0123 2013-04-01 10.816187
#15 Clothing 10.3         0.0123 2013-05-01 10.949226
#16 Clothing 10.3         0.0123 2013-06-01 11.083901
#17 Clothing 10.3         0.0123 2013-07-01 11.220233
#18 Clothing 10.3         0.0123 2013-08-01 11.358242
#19 Clothing 10.3         0.0123 2013-09-01 11.497948
#20 Clothing 10.3         0.0123 2013-10-01 11.639373

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM