使用基于邻居的均值更改特定值

时间:2016-04-04 09:02:44

标签: r

我的数据集的值为100到200,但数据中有一些峰值。 我不想用rollmean或rollaplly来平滑整个数据集。

我想以这种方式工作:

  1. 找到条件(值> 300)

  2. 的这些峰值
  3. 用平均值/中位数替换这些太大的值 从10个近邻值计算得出。

  4. 伪代码示例:

    data[n] = spike
    
    data[n] = mean(from data[n-5] to data[n+5])
    

    就像在整个数据集上使用窗口函数一样,只在数据的某些点上使用。

    提前谢谢

1 个答案:

答案 0 :(得分:0)

我喜欢这个问题。典型的移动平均值/ k-最近邻域估计。非参数方法。以下应该有效。

foo <- function(x, thresh = 300, h = 5, window.fun = mean) {
  spikes.loc <- which(x > thresh)
  low.bound <- spikes - h
  up.bound <- spikes + h
  N <- length(spikes.loc)
  x.hat <- x
  for (i in 1:N) x.hat[spikes.loc[i]] <- window.fun(x[low.bound[i]:up.bound[i]])
  return(x.hat)
  }

此函数采用原始观测向量x,阈值,窗口大小(平滑参数)以及用户指定的窗口函数。返回的值是矢量平滑数据。它仅与尖峰点的原始数据不同。窗函数的常见选择是密度函数,因此最终得到所有相邻数据的加权平均值。

请注意,我假设你的数据是均匀间隔的,所以一个简单的索引x [i-h]:x [i + h]给出了一个合理的邻域。在更一般的设置中,窗口基于欧氏距离,但是天真地花费O(N * N),其中N是观察的数量,这是昂贵的。

在R中,有内置的非参数估计/平滑工具。最基本的是kernel smoothing,是移动平均线的推广。它使用FFT算法以O(N log(N))成本进行快速计算。请参阅?ksmooth。更高级的是KernSmoothsm个包。