用先前值的小数增加替换 NA 值

Replace NA values with a fractional increase in previous values

如果我有以下数据框

df <- tribble(
      ~year, ~value,
      2011, 10,
      2012, 15,
      2013, 20,
      2014, NA,
      2015, NA
    )

我想用之前值增加 10% 来填充 2014 年和 2015 年的 NA 值,这样 2014 年将是 22,2015 年将是 24.2。我知道如何用上一个或下一个值填充它,但在这种情况下找不到任何信息。使用 dplyr 管道的方法会更有帮助。

你可以在 base R 中使用 Reduce :

Reduce(function(x, y) if(is.na(y)) x * 1.1 else y, df$value, accumulate = TRUE)
#[1] 10.0 15.0 20.0 22.0 24.2

如果您想要 tidyverse 解决方案,请使用 accumulate

library(dplyr)
library(purrr)

df %>% mutate(value = accumulate(value, ~if(is.na(.y)) .x * 1.1 else .y))

#   year value
#  <dbl> <dbl>
#1  2011  10  
#2  2012  15  
#3  2013  20  
#4  2014  22  
#5  2015  24.2

.x.y in accumulate(或xy in Reduce)分别是当前值和下一个值.因此,对于第一次迭代,.x 为 10,.y 为 15,接下来 .x 将变为 15,而 .y 将变为 20,依此类推 [=] 中的所有值25=]。我们在这里检查下一个值 (.y) 是否为 NA 然后将下一个值替换为前一个值 (.x) 的 1.1 倍,如果不是 NA 则保留它原样。

Base R 在向量化计算中使用 rep()-etition 和 cumprod()

multiplier <- 1.1
is_na <- is.na(df$value)
df$value[is_na] <- with(
  df, 
  tail(cumprod(c(tail(value[!is_na], 1), rep(multiplier, sum(is_na)))), -1)
)

或使用 while() 循环:

multiplier <- 1.1 
while(any(is.na(df$value))){
  idx <- with(df, head(which(is.na(value)), 1))
  df$value[idx] <- with(
    df, 
    value[(idx-1)] * multiplier
  )
}

或使用递归:

multiplier <- 1.1 
cum_prod_estimate <- function(vec, multiplier=1.1){
  if(all(!(is.na(vec)))){
    return(vec)
  }else{
    idx <- Position(is.na, vec)
    vec[idx] <- vec[idx-1] * multiplier
    return(cum_prod_estimate(vec))
  }
}

df$value <- cum_prod_estimate(df$value)