将 NA 替换为 R 向量中先前数字的修改版本
Replace NA with modified version of previous number in R vector
我有一个带有一些 NA 的向量,我想用之前的非 NA 值减去 0.1 来替换其中的一些 NA。如果 NA 的字符串超过一定长度(例如 2),我也不想替换 NA。这是一个例子
x <- c(1:3, NA, 4, NA, NA, 5, NA, NA, NA, 6, NA)
我想制作一个看起来像
的矢量
x_prime <- c(1:3, 2.9, 4, 3.9, 3.8, 5, NA, NA, NA, 6, 5.9)
打印出来的样子:
> x_prime
[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 5.9
作为一个额外的复杂问题,我想跟踪我修改的索引,所以我还想要一个看起来像
的向量
idx <- c(4, 6, 7, 13)
如果 NA 中的第一个位置(以及所有领先的 NA),我们可以不做任何事情。
我在 SO 上发现了一些类似的问题,例如 this,并且我尝试了与那里介绍的功能类似的功能,但没有成功。有任何想法吗?提前谢谢你。
这是 diff
和 cumsum
到 split
的选项
library(zoo)
lst1 <- split(x, cumsum(c( diff(!is.na(x)) < 0, TRUE)))
unname(unlist(lapply(lst1, function(x) if(sum(is.na(x)) <= 2)
na.locf0(x) -seq(0, length.out = length(x), by = 0.1) else x)))
#[1] 1.0 1.9 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 NA
第二种情况
as.vector(unlist(sapply(split(seq_along(x) * is.na(x),
cumsum(c( diff(!is.na(x)) < 0, TRUE))),
function(x) x[x != 0 & sum(x != 0) <=2])))
#[1] 4 6 7 13
ave
的基础 R 选项:
len <- 2
x1 <- ave(x, cumsum(!is.na(x)), FUN = function(v) {
if(length(v) > len + 1) v
else v[1] - seq(0, by= 0.1, length.out = length(v))
})
x1
#[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 5.9
我们创建了一组 NA
个值以及第一个非 NA 值,并在 ave
中使用它。如果组长度大于 len + 1
(+ 1
因为每个组中的第一个值不是 NA
)那么我们不改变组中的任何内容,否则我们减去 0、0.1、从组中的第一个值开始 0.2。
要获得替换的位置,请找出 x
中的 NA
而不是 x1
.
中的 NA
which(is.na(x) & !is.na(x1))
#[1] 4 6 7 13
版本使用包 imputeTS
使用 na_locf
和参数 maxgap
:
library("imputeTS")
x_prime <- na_locf(x, maxgap = 2)
idx <- which(is.na(imp) != is.na(x))
x_prime[idx] <- x_prime[idx] - 0.1
结果:
x_prime
[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.9 5.0 NA NA NA 6.0 5.9
idx
[1] 4 6 7 13
编辑:
简短的补充,似乎我对“用以前的非 NA 值减去 0.1 替换 NA”的解释不同。不确定它是否是故意的,但你似乎更喜欢负 0.1 也完成,当结转之前的值是一个推算值时。
我有一个带有一些 NA 的向量,我想用之前的非 NA 值减去 0.1 来替换其中的一些 NA。如果 NA 的字符串超过一定长度(例如 2),我也不想替换 NA。这是一个例子
x <- c(1:3, NA, 4, NA, NA, 5, NA, NA, NA, 6, NA)
我想制作一个看起来像
的矢量x_prime <- c(1:3, 2.9, 4, 3.9, 3.8, 5, NA, NA, NA, 6, 5.9)
打印出来的样子:
> x_prime
[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 5.9
作为一个额外的复杂问题,我想跟踪我修改的索引,所以我还想要一个看起来像
的向量idx <- c(4, 6, 7, 13)
如果 NA 中的第一个位置(以及所有领先的 NA),我们可以不做任何事情。
我在 SO 上发现了一些类似的问题,例如 this,并且我尝试了与那里介绍的功能类似的功能,但没有成功。有任何想法吗?提前谢谢你。
这是 diff
和 cumsum
到 split
library(zoo)
lst1 <- split(x, cumsum(c( diff(!is.na(x)) < 0, TRUE)))
unname(unlist(lapply(lst1, function(x) if(sum(is.na(x)) <= 2)
na.locf0(x) -seq(0, length.out = length(x), by = 0.1) else x)))
#[1] 1.0 1.9 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 NA
第二种情况
as.vector(unlist(sapply(split(seq_along(x) * is.na(x),
cumsum(c( diff(!is.na(x)) < 0, TRUE))),
function(x) x[x != 0 & sum(x != 0) <=2])))
#[1] 4 6 7 13
ave
的基础 R 选项:
len <- 2
x1 <- ave(x, cumsum(!is.na(x)), FUN = function(v) {
if(length(v) > len + 1) v
else v[1] - seq(0, by= 0.1, length.out = length(v))
})
x1
#[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0 NA NA NA 6.0 5.9
我们创建了一组 NA
个值以及第一个非 NA 值,并在 ave
中使用它。如果组长度大于 len + 1
(+ 1
因为每个组中的第一个值不是 NA
)那么我们不改变组中的任何内容,否则我们减去 0、0.1、从组中的第一个值开始 0.2。
要获得替换的位置,请找出 x
中的 NA
而不是 x1
.
NA
which(is.na(x) & !is.na(x1))
#[1] 4 6 7 13
版本使用包 imputeTS
使用 na_locf
和参数 maxgap
:
library("imputeTS")
x_prime <- na_locf(x, maxgap = 2)
idx <- which(is.na(imp) != is.na(x))
x_prime[idx] <- x_prime[idx] - 0.1
结果:
x_prime
[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.9 5.0 NA NA NA 6.0 5.9
idx
[1] 4 6 7 13
编辑: 简短的补充,似乎我对“用以前的非 NA 值减去 0.1 替换 NA”的解释不同。不确定它是否是故意的,但你似乎更喜欢负 0.1 也完成,当结转之前的值是一个推算值时。