如何在给定最大间隙参数的情况下用零替换连续的 NA(在 R 中)
How to replace consecutive NAs with zero given a max gap parameter (in R)
我想用零替换每行所有连续的 NA
值,但前提是连续的 NA
的数量小于参数 maxgap
.
这与函数非常相似zoo::na.locf
x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
zoo::na.locf(x, maxgap = 2, na.rm = FALSE)
给予
[1] NA 1 2 3 3 3 5 6 7 NA NA NA
有两点与我的目标不同:
我也想替换前导 NA,我想用 0 而不是最后一个非 NA 值替换 2 个连续的 NA。
我想得到
0 1 2 3 0 0 5 6 7 NA NA NA
我如何在 R 中执行此操作。我可以使用 tidyverse 中的函数吗?
我们可以使用rle
来做到这一点
f1 <- function(vec){
rl <- rle(is.na(vec))
lst <- within.list(rl, {
i1 <- seq_along(values)==1
i2 <- seq_along(values) != length(values)
values[!((lengths==2 & values & i2)|
(values & i1))] <- FALSE
})
vec[inverse.rle(lst)] <- 0
vec
}
f1(x)
#[1] 0 1 2 3 0 0 5 6 7 NA NA NA
如果 y
是 na.locf
行的结果,那么如果 y[i]
不是 NA 但 x[i]
是 NA 那么它被替换,所以给它赋值 0。此外,如果它是前导 NA,当下面的 cumsum(...)
项为 0 时出现,则也将其替换。
replace(y, (!is.na(y) & is.na(x)) | cumsum(!is.na(y)) == 0, 0)
## [1] 0 1 2 3 0 0 5 6 7 NA NA NA
你可以,例如这样做:
require(data.table)
require(dplyr)
x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
my_replace <- function(x, n, maxgap){
if(is.na(x[1]) && n <= maxgap){
x <- 0
}
x
}
data.frame(x, y=x) %>%
group_by(data.table::rleid(x)) %>%
mutate(x = my_replace(x, n(), 2), y = my_replace(y, n(), 1)) %>%
ungroup() %>%
select(x,y)
这允许您按列设置 maxgap
:for x 2
for y 1
.
这导致:
# A tibble: 12 × 2
x y
<dbl> <dbl>
1 0 0
2 1 1
3 2 2
4 3 3
5 0 NA
6 0 NA
7 5 5
8 6 6
9 7 7
10 NA NA
11 NA NA
12 NA NA
我想用零替换每行所有连续的 NA
值,但前提是连续的 NA
的数量小于参数 maxgap
.
这与函数非常相似zoo::na.locf
x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
zoo::na.locf(x, maxgap = 2, na.rm = FALSE)
给予
[1] NA 1 2 3 3 3 5 6 7 NA NA NA
有两点与我的目标不同: 我也想替换前导 NA,我想用 0 而不是最后一个非 NA 值替换 2 个连续的 NA。
我想得到
0 1 2 3 0 0 5 6 7 NA NA NA
我如何在 R 中执行此操作。我可以使用 tidyverse 中的函数吗?
我们可以使用rle
来做到这一点
f1 <- function(vec){
rl <- rle(is.na(vec))
lst <- within.list(rl, {
i1 <- seq_along(values)==1
i2 <- seq_along(values) != length(values)
values[!((lengths==2 & values & i2)|
(values & i1))] <- FALSE
})
vec[inverse.rle(lst)] <- 0
vec
}
f1(x)
#[1] 0 1 2 3 0 0 5 6 7 NA NA NA
如果 y
是 na.locf
行的结果,那么如果 y[i]
不是 NA 但 x[i]
是 NA 那么它被替换,所以给它赋值 0。此外,如果它是前导 NA,当下面的 cumsum(...)
项为 0 时出现,则也将其替换。
replace(y, (!is.na(y) & is.na(x)) | cumsum(!is.na(y)) == 0, 0)
## [1] 0 1 2 3 0 0 5 6 7 NA NA NA
你可以,例如这样做:
require(data.table)
require(dplyr)
x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
my_replace <- function(x, n, maxgap){
if(is.na(x[1]) && n <= maxgap){
x <- 0
}
x
}
data.frame(x, y=x) %>%
group_by(data.table::rleid(x)) %>%
mutate(x = my_replace(x, n(), 2), y = my_replace(y, n(), 1)) %>%
ungroup() %>%
select(x,y)
这允许您按列设置 maxgap
:for x 2
for y 1
.
这导致:
# A tibble: 12 × 2
x y
<dbl> <dbl>
1 0 0
2 1 1
3 2 2
4 3 3
5 0 NA
6 0 NA
7 5 5
8 6 6
9 7 7
10 NA NA
11 NA NA
12 NA NA