使用先前值的组合来估算 NA,无需循环

问题描述 投票:0回答:1

继续上一个问题,我需要将过去几年的缺失估算为R中前几年的组合。在下面的数据中,我需要将2020年估算为2019年、2018年和2017年的线性组合,并将2021年估算为2020年的组合、2019、2018。

> comb1 <- cbind(CJ(letters[1:4], 2000:2019), rnorm(80,2,1)) 
> comb2 <-  cbind(CJ(letters[1:4], 2020:2024), data.frame(rep(NA, 20)))
> colnames(comb1) <- c("state","year","v")
> colnames(comb2) <- c("state","year","v")
> 
> comb <- rbind(comb1, comb2)
> comb <- comb[order(comb$state, comb$year),]
>

我可以循环执行(如下),但由于我的数据很大(我有很多“状态”),所以速度非常慢。有人知道如何以更有效的方式做到这一点吗?

> library(dplyr)
> vlist <- unique(comb$state)
> for (i in vlist) {
> for (j in (2002:2024)) {
> value <- 0.65*comb$v[comb$year==j-1 & comb$stat==i] + 0.25*comb$v[comb$year==j-2 & comb$state==i] + 0.10*comb$v[comb$year==j-3 & comb$state==i]
> if (is.na(comb$v[comb$year==j & comb$state==i])) {
> comb$v[comb$year==j & comb$state==i] <- value
>     }
>   }
> }
> 

我设法部分地通过向量来完成它,所以速度更快,但更优雅的解决方案会很好......

for (j in (2002:2024)) {
  
  comb$v_1 <- ave(comb$v, comb$state, FUN = dplyr::lag)
  comb$v_2 <- ave(comb$v_1, comb$state, FUN = dplyr::lag) 
  comb$v_3 <- ave(comb$v_2, comb$state, FUN = dplyr::lag) 
  
  comb$imp <- 0.65*comb$v_1 + 0.25*comb$v_2 + 0.10*comb$v_3
  comb$v <- ifelse(is.na(comb$v)&comb$year==j, comb$imp, comb$v)
  
 comb$v_1 <- NULL
 comb$v_2 <- NULL
 comb$v_3 <- NULL
 comb$imp <- NULL
}
r lag
1个回答
0
投票

有点复杂,但是有窍门:

首先,创建一个简单的函数来根据向量的最后三个数字计算要插补的值:

impute <- function(x) {
  sum(tail(x, 3) * c(0.1, 0.25, 0.65))
}

然后是另一个简单的函数,只要找到

NA
(或者只是沿着向量向前移动),就会调用此函数:

roll_impute <- function(x, y) {
  if (is.na(x)) {
    c(x, impute(x))
  } else {
    c(x, y)
  }
}

现在只需使用

reduce()
包中的
purrr
即可将此函数递归地应用于
v
。 由于您希望每个
state
单独工作,因此我们预先将
data.frame
分组:

comb %>%
  group_by(state) %>%
  mutate(v = reduce(v, roll_impute))
© www.soinside.com 2019 - 2024. All rights reserved.