按组用数字序列填充 NA

Fill NAs with numerical sequence by group

我想按组用数字序列唯一地填充 NA。

这是一个最小的数据集:

d
#>    id year
#> 1   1 1998
#> 2   1 1999
#> 3   1 2001
#> 4   1   NA
#> 5   1   NA
#> 6   2 1997
#> 7   2 1999
#> 8   2 2001
#> 9   2   NA
#> 10  2   NA
#> 11  3 1997
#> 12  3 1998
#> 13  3 1999
#> 14  3 2000
#> 15  3 2001

#data set
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L), year = structure(list(year = c(1997L, 1998L, 
1999L, 2000L, NA, 1998L, 1999L, 2001L, NA, NA, 1998L, 1999L, 
2000L, 2001L, NA)), class = "data.frame", row.names = c(NA, -15L
))), row.names = c(NA, -15L), class = "data.frame")

NAs应替换为1997年至2001年的数字序列的未已取值;因此结果数据框如下所示:

#>    id year
#> 1   1 1997
#> 2   1 1998
#> 3   1 1999
#> 4   1 2000
#> 5   1 2001
#> 6   2 1997
#> 7   2 1998
#> 8   2 1999
#> 9   2 2000
#> 10  2 2001
#> 11  3 1997
#> 12  3 1998
#> 13  3 1999
#> 14  3 2000
#> 15  3 2001

#data set
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L), year = c(1997L, 1998L, 1999L, 2000L, 2001L, 
1997L, 1998L, 1999L, 2000L, 2001L, 1997L, 1998L, 1999L, 2000L, 
2001L)), class = "data.frame", row.names = c(NA, -15L))

我们可以用coalesce

library(dplyr)
d$year <- coalesce(prodNA(d[2],noNA=0.3)$year, d$year)

如果需要分组

library(dplyr)
d %>% 
   group_by(id) %>% 
   mutate(year = coalesce(prodNA(cur_data()["year"], noNA = 0.3)$year, year)) %>%
   ungroup

-输出

# A tibble: 15 × 2
      id  year
   <int> <int>
 1     1  1997
 2     1  1998
 3     1  1999
 4     1  2000
 5     1  2001
 6     2  1997
 7     2  1998
 8     2  1999
 9     2  2000
10     2  2001
11     3  1997
12     3  1998
13     3  1999
14     3  2000
15     3  2001

数据

set.seed(1)
d <- data.frame(id = rep(1:3,each=5),
       year = rep(1997:2001,3))

基础 R 备选方案:

d$year2 <- ave(d$year, d$id, FUN = function(z) { z[is.na(z)] <- setdiff(1997:2001, z); z;})
d
#    id year year2
# 1   1 1998  1998
# 2   1 1999  1999
# 3   1 2001  2001
# 4   1   NA  1997
# 5   1   NA  2000
# 6   2 1997  1997
# 7   2 1999  1999
# 8   2 2001  2001
# 9   2   NA  1998
# 10  2   NA  2000
# 11  3 1997  1997
# 12  3 1998  1998
# 13  3 1999  1999
# 14  3 2000  2000
# 15  3 2001  2001

ave 是一个简单的函数,用于根据分组标准(类似 list 的第二个参数)对向量(第一个参数)进行操作。该函数一次被赋予一组值的单个向量,因此对于这些数据,anon-func 被调用了三次。 ave 的唯一陷阱是 ave 总是强制函数的 return 值与输入向量相同 class,这可能令人沮丧且荒谬(我确定在某些时候这种行为是有原因的)。

知道任何时候的 z 都是一次一组的 year 的全部,该函数的内部工作原理很简单:将所有 NA 值替换为1997:2001 中缺少值。不过,这有一个很大的警告:这假定 z 中唯一合法的值是 c(NA, 1997:2001);如果还有其他问题,这可能会 fail/explode 或导致您邻居的汽车失火。

从这个意义上说,这种方法有点脆弱。为了更有弹性,我们可能需要一些津贴。例如,在数据中保留 1997:2001 之外的值是否可以,或者它们是否也应该被替换?如果不是,那么是否有一种启发式方法可以确定将哪些缺失值归因于 NA 值?


数据

d <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), year = c(1998L, 1999L, 2001L, NA, NA, 1997L, 1999L, 2001L, NA, NA, 1997L, 1998L, 1999L, 2000L, 2001L)), class = "data.frame", row.names = c(NA, -15L))