用先前值的小数增加替换 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
(或x
和y
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)
如果我有以下数据框
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
(或x
和y
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)