【问题标题】:Efficiently apply a growth rate to an initial value for varying growth rates over many years有效地将增长率应用于多年来不同增长率的初始值
【发布时间】:2020-03-14 21:22:17
【问题描述】:

我有一个关于未来增长率的大型数据集和每个人的初始值。

我想将 t=0 时的增长率与初始值 (t=0) 相乘,得到 t=1 时的值。这个 t=1 值,我想乘以 t=1 时的增长率,依此类推。

我目前使用循环执行此操作,但考虑到我在很长一段时间内有很多人,这非常慢,我觉得必须有一种更智能(更优雅)的方式来执行此操作。

我特别想使用 dplyr 函数来做到这一点。

#Create a sample df
df <- data.frame(id=rep(c("A","B"),each=5),
           year=rep(1:5,2),
           value = NA)

set.seed(123)
growth_rates <- data.frame(id=rep(c("A","B"),each=5),
                           year=rep(1:5,2),
                           value = runif(10,0.95,1.1))

# pick an initial value (in reality this is given)
df[df$year==1&df$id=="A","value"] <- 5
df[df$year==1&df$id=="B","value"] <- 7

for (i in 2:5){
  df[df$year == i,"value"] <- df[df$year == i-1,"value"]*growth_rates[growth_rates$year == i-1,"value"]
}

感谢您的帮助!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这是一个简洁的 dplyr 解决方案,在 growth_ratescumprod 上使用 lag

    initial_vals <- c(5, 7)
    
    growth_rates %>%
      group_by(id) %>% 
      mutate(cumulative = lag(cumprod(value), default = 1)) %>%
      mutate(value = cumulative * initial_vals[match(id, c("A", "B"))]) %>%
      select(-cumulative)
    #> # A tibble: 10 x 3
    #> # Groups:   id [2]
    #>    id     year value
    #>    <fct> <int> <dbl>
    #>  1 A         1  5   
    #>  2 A         2  4.97
    #>  3 A         3  5.30
    #>  4 A         4  5.36
    #>  5 A         5  5.81
    #>  6 B         1  7   
    #>  7 B         2  6.70
    #>  8 B         3  6.89
    #>  9 B         4  7.47
    #> 10 B         5  7.72
    
    

    【讨论】:

      【解决方案2】:

      在为每个组分配初始值后,我们可以使用purrr中的accumulate

      library(dplyr)
      library(purrr)
      
      initial_value <- c(5, 7)
      growth_rates$ans[!duplicated(df$id)] <- initial_value
      
      
      growth_rates %>%
         group_by(id) %>%
         mutate(ans = accumulate(value[-n()], `*`, .init = first(ans)))
      
      
      #   id     year value   ans
      #   <fct> <int> <dbl> <dbl>
      # 1 A         1 0.993  5   
      # 2 A         2 1.07   4.97
      # 3 A         3 1.01   5.30
      # 4 A         4 1.08   5.36
      # 5 A         5 1.09   5.81
      # 6 B         1 0.957  7   
      # 7 B         2 1.03   6.70
      # 8 B         3 1.08   6.89
      # 9 B         4 1.03   7.47
      #10 B         5 1.02   7.72
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多