根据上一个和下一个正确值替换向量中的值?

Gre*_*nXY 3 r

如果我有一个像

x = c(1, 2, -1, -2, 5, 6, 7, -1, -2, -3, 8, 9)
Run Code Online (Sandbox Code Playgroud)

我希望对于每个负值,向前看并计算前方有多少个负值,包括当前值。所以结果看起来像

y = c(0, 0, 2, 1, 0, 0, 0, 3, 2, 1, 0, 0)
Run Code Online (Sandbox Code Playgroud)

我的最终目标是使用这些结果根据最接近的正值的平均值创建负值的替换值。在这种情况下,我希望结果是:

result = {1,2,(2+5)/2,(2+5)/2,5,6,7,(7+8)/2,(7+8)/2,(7+8)/2,8,9}
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用mutatelead使用不同的偏移量来执行此操作,但是必须有更简单的方法吗?

Fra*_*ank 6

这是@Khashaa的答案启发的另一种方式:

approx(replace(x, x < 0, NA), xout = seq_along(x), 
  method = "constant", f = 0.5, rule = 2)$y
# [1] 1.0 2.0 3.5 3.5 5.0 6.0 7.0 7.5 7.5 7.5 8.0 9.0
Run Code Online (Sandbox Code Playgroud)

伪代码的工作方式。令X = replace(x,x <0,NA)。

X = 1  2 NA NA  5  6  7 NA NA NA  8  9
Run Code Online (Sandbox Code Playgroud)

我们xout使用数据对函数X(i)进行插值,其中i取= 1..12中的值

  {[i, X(i)] : X(i) not NA, i = 1..12} 
= {[i, X(i)] : i = 1, 2, 5, 6, 7, 11, 12}
Run Code Online (Sandbox Code Playgroud)

由于我们已经在X(i)上获得了不属于NA的数据,因此我们只需要填充NA的间隔,即i = 3、4、8、9、10。

  • method =“常数”填充NA的每个间隔,即i = 3-4和i = 8-10,并根据两个最近的观测值计算出一个值
  • f = 0.5相等地权衡两个观察值
  • rule = 2根据最近的观测值在向量的开头或结尾填充丢失的间隔(不适用于此示例)

有关完整文档,请参见?approx

(感谢@thothal在评论中进行解释和更正。)

  • 多么漂亮的解决方案!+1由于xout = seq_along(x),它可以对向量进行插值以获得与原始向量相同的长度。如果`length(xout)== length(x)`只会返回`x`。但是,在“大约”中,NA被删除,这意味着这些被删除的值必须被替换。由于“方法=常数”和“ f = .5”,我们通过平均相邻点来实现。不过,有一件事,您需要添加`rule = 2`来处理`x &lt;-c(-1,1,2)` (2认同)