按组用数字序列填充 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))
我想按组用数字序列唯一地填充 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))