首页 > 解决方案 > 按组计算 dplyr 中具有先前值的字段

问题描述

我想使用 dplyr 使用它的先前值来计算一个字段。for 循环可以完成这项工作,但我想按不同的st组计算。我了解 mutate (lag or ave) 不能使用未初始化的字段。

df <- data.frame(st = rep(c('a','b', 'c'), each = 5),
                     z = rep(c(10,14,12), each = 5),
                     day = rep(1:5, 3),
                     GAI = rep(0:4, 3),
                     surfT = sample(1:15))
df %>%
   group_by(st) %>%
   mutate(soilT = lag(soilT, order_by = day) + (surfT - lag(soilT,
            order_by = day))*0.24*exp(-z*0.017)*exp(-0.15*GAI))

或者

df %>%
  group_by(st) %>%
  mutate(soilT = ave(soilT, c(st), FUN=function(x) c(0, soilT + (surfT - soilT)))
         *0.24*exp(-z*0.017)*exp(-0.15*GAI)) 

如何通过st组在 dplyr 中计算一个简单的 for 循环:

  df$soilT <- 0
  for (i in 2:dim(df)[1]){
    df$soilT[i]=df$soilT[i-1] + (df$surfT[i] - df$soilT[i-1])
                                 *0.24*exp(-z[i]*0.017)*exp(-0.15*GAI[i])
  }

标签: rfunctiondplyriteration

解决方案


我们可以使用accumulatefrompurrr获取前一行的输出作为当前行的输入。

library(dplyr)

result <- df %>%
           group_by(st) %>%
           mutate(soilT = purrr::accumulate(2:n(), 
            ~.x + (surfT[.y] - .x)*0.24*exp(-z[.y]*0.017)*exp(-0.15*GAI[.y]), 
            .init = 0))

推荐阅读