使用先前计算结果在dplyr中进行迭代计算

使用先前计算结果在dplyr中进行迭代计算,r,dplyr,tidyverse,R,Dplyr,Tidyverse,我希望使用以下逻辑对数据帧中的字段执行计算: 如果是basevalue!=NA,将basevalue指定给结果 如果basevalue==NA,则取上一个结果,乘以乘数字段,并将其作为结果输出 假设第一个值从不为NA,因此始终存在种子值。我希望按数据组执行计算(dplyr::group_by) 以下代码给出了一个reprex: basevalue <- c(2,5,NA,NA,NA,NA) multiplier <- c(3.2,1.1,1.8,1.3,1.5,1.2

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

  • 如果是basevalue!=NA,将basevalue指定给结果
  • 如果basevalue==NA,则取上一个结果,乘以乘数字段,并将其作为结果输出
假设第一个值从不为NA,因此始终存在种子值。我希望按数据组执行计算(dplyr::group_by)

以下代码给出了一个reprex:

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)

basevalue以下是一种使用
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)
}

以下是使用
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)
}

您可以使用purrr中的
acgregate2
函数来实现这一点,该函数旨在跨两个向量应用这种递归关系

library(dplyr)
library(purrr)

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

dfIn %>%
  mutate(lst = accumulate2(basevalue, multiplier[-1], calculate),
         result = unlist(lst))
库(dplyr)
图书馆(purrr)
计算%
突变(lst=累加2(基值,乘数[-1],计算),
结果=未列出(lst))
注二:

  • multiplier[-1]
    丢弃第一个乘数值,因为
    accumulate
    希望它比第一个参数短一个(请注意,您永远不会使用第一个乘数值,因为在该点上没有“previous”值)
  • acgregate2
    的结果是一个列表,因此我们添加
    unlist()
    将其转换为一个向量

您可以使用purrr中的
累加器2
函数来实现这一点,该函数旨在跨两个向量应用这种递归关系

library(dplyr)
library(purrr)

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

dfIn %>%
  mutate(lst = accumulate2(basevalue, multiplier[-1], calculate),
         result = unlist(lst))
库(dplyr)
图书馆(purrr)
计算%
突变(lst=累加2(基值,乘数[-1],计算),
结果=未列出(lst))
注二:

  • multiplier[-1]
    丢弃第一个乘数值,因为
    accumulate
    希望它比第一个参数短一个(请注意,您永远不会使用第一个乘数值,因为在该点上没有“previous”值)
  • acgregate2
    的结果是一个列表,因此我们添加
    unlist()
    将其转换为一个向量

当我尝试使用dplyr::mutate with lag(result)和if_else子句时,我无法有条件地提取上一个结果并在第一个结果之后获取NAs。当我尝试使用dplyr::mutate with lag(result)和if_else子句时,我无法有条件地获取上一个结果并在第一个结果之后获取NAs。如果在
group_by()
中应用,这将不起作用,因为specifies@DavidRobinson据我所知,会的。为什么您认为它不适用于
group\u by
?如果应用于
group\u by()
,这将不起作用specifies@DavidRobinson据我所知,会的。为什么您认为它不能与
group\U by
一起使用?嗯。。。它起作用了。我不确定我是否真的理解,但它确实起作用了!好。。。它起作用了。我不确定我是否真的理解,但它确实起作用了!