【问题标题】:R - mutate based on previous values in the same columnR - 根据同一列中的先前值进行变异
【发布时间】:2021-10-28 13:16:03
【问题描述】:

数据:

df <- data.frame(year = c(2018, 2019, 2020, 2021),
                 growth = c(0.05, 0.1, 0.08, 0.06),
                 size = c(100, NA, NA, NA))

  year growth size
1 2018   0.05  100
2 2019   0.10   NA
3 2020   0.08   NA
4 2021   0.06   NA 

我有2018 年的规模和随后几年的增长率。我的目标是将以后每一年的大小计算为size[i] = size[i-1] * (1 + growth[i])。我可以用 for 循环来做到这一点:

for (i in (2:nrow(df))) {
  df$size[i] <- df$size[i-1] * (1 + df$growth[i]) 
}

  year growth    size
1 2018   0.05 100.000
2 2019   0.10 110.000
3 2020   0.08 118.800
4 2021   0.06 125.928

但我找不到dplyr 做同样事情的方式,例如mutate。希望听到你的想法。谢谢!

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    由于size 的第一个值实际上是该列其余部分的乘法常数,我们可以只使用1 + growthcumprod(累积积)来获得乘以size[1] 的因子填充size 列的其余部分。

    稍微复杂的是您的算法必须忽略growth 的第一个值。我们可以通过使用leadlag 的组合来解决这个问题。

    因此,以下内容无需使用循环即可工作。

    library(dplyr)
    
    mutate(df, size = lag(size[1] * cumprod(lead(growth + 1)), default = size[1]))
    
    #>   year growth    size
    #> 1 2018   0.05 100.000
    #> 2 2019   0.10 110.000
    #> 3 2020   0.08 118.800
    #> 4 2021   0.06 125.928
    

    【讨论】:

    • 这在我的示例中非常有用。如果我想为分组数据框运行它,如何调整它?例如:df &lt;- data.frame(country = c("A", "A", "A", "A", "B", "B", "B", "B"), year = c(2018, 2019, 2020, 2021, 2018, 2019, 2020, 2021), growth = c(0.05, 0.1, 0.08, 0.06, 0.02, 0.08, 0.04, 0.04), size = c(100, NA, NA, NA, 200, NA, NA, NA)) %&gt;% group_by(country)?
    • @denisafonin 它应该仍然适用于分组数据帧。使用您包含在 cmets 中的数据框,它似乎确实给出了预期的结果。
    • 对,它实际上运行良好,在我的代码中有一个类型。非常感谢!
    【解决方案2】:

    purrr::reduce的解决方案:

    library(tidyverse)
    
    df <- data.frame(year = c(2018, 2019, 2020, 2021),
                     growth = c(0.05, 0.1, 0.08, 0.06),
                     size = c(100, NA, NA, NA))
    
    reduce(2:nrow(df), function(x,y) 
      {x$size[y] <- x$size[y-1]*(1+x$growth[y]); x}, .init=df)
    #>   year growth    size
    #> 1 2018   0.05 100.000
    #> 2 2019   0.10 110.000
    #> 3 2020   0.08 118.800
    #> 4 2021   0.06 125.928
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-25
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多