【问题标题】:Iterative calculation in dplyr using result of previous calculation使用先前计算的结果在 dplyr 中进行迭代计算
【发布时间】:2021-01-07 01:59:32
【问题描述】:

我希望使用以下逻辑对数据框中的字段执行计算:

  • 如果基值 != NA,则将基值分配给结果
  • 如果基值 == NA,则取上一个结果,将其乘以乘数字段并将其作为结果输出。

假设第一个值永远不会是 NA,所以总会有一个种子值。我希望按数据组执行计算 (dplyr::group_by)

以下代码给出了一个代表:

basevalue <- c(2,5,NA,NA,NA,NA)      
multiplier <- c(3.2,1.1,1.8,1.3,1.5,1.2)
previous_result <- c(NA,2,5,9,11.7,17.55)
result<- c(2,5,9,11.7,17.55,21.06)
logic <- c(rep("basevalue != NA, so take base value",2), rep("basevalue == NA, so take lag(result) * multiplier",4))

dfIn <- data.frame(basevalue,multiplier)
dfOut <- data.frame(basevalue,multiplier, result, previous_result, logic)

有没有办法使用简单的 dplyr / base R / tidyverse 逻辑来实现这一点,还是我需要使用诸如 zoo 之类的专业包?

【问题讨论】:

  • 当我尝试将 dplyr::mutate 与 lag(result) 和 if_else 子句一起使用时,我无法有条件地获取先前的结果并在第一个结果之后获得 NA。

标签: r dplyr tidyverse


【解决方案1】:

您可以使用 purrr 中的 accumulate2 函数来执行此操作,该函数旨在将这种递归关系应用于两个向量。

library(dplyr)
library(purrr)

calculate <- function(previous, basevalue, multiplier) {
  coalesce(basevalue, multiplier * previous)
}

dfIn %>%
  mutate(lst = accumulate2(basevalue, multiplier[-1], calculate),
         result = unlist(lst))

两个音符:

  • multiplier[-1] 丢弃了第一个乘数值,因为accumulate 期望它比第一个参数短一个(请注意,您永远不会使用第一个乘数值,因为此时没有“先前”值)。
  • accumulate2的结果是一个列表,所以我们加上unlist()把它变成一个向量。

【讨论】:

  • 嗯......它的工作原理。我不确定我是否真的了解如何,但它确实可以完成这项工作!
【解决方案2】:

这是使用for 循环执行此操作的一种方法:

calculate_result <- function(b, m) {
  r <- b
  inds <- which(is.na(b))
  for(i in inds) {
    r[i] <- r[i-1] * m[i]
  }
  return(r)
}

将此功能与dplyr 一起应用,以便您以后可以使用group_by

library(dplyr)
dfIn %>% mutate(result = calculate_result(basevalue, multiplier))

#  basevalue multiplier result
#1         2        3.2   2.00
#2         5        1.1   5.00
#3        NA        1.8   9.00
#4        NA        1.3  11.70
#5        NA        1.5  17.55
#6        NA        1.2  21.06

【讨论】:

  • 这在group_by() 中应用时不起作用,正如 OP 指定的那样
  • @DavidRobinson 据我了解,它会的。为什么你认为它不适用于group_by
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
相关资源
最近更新 更多