如何使用前一个和后一个数据点对R数据集中的异常值进行平均?

时间:2012-11-12 08:39:09

标签: r dataset average outliers datapoint

我有一个大型数据集,并且已将异常值定义为高于第99个或低于第1个百分位数的那些值。

我想用这些异常值和它们之前和之后的数据点取平均值,然后用新数据集中的平均值替换所有3个值。

如果有人知道如何做到这一点,我会非常感谢你的回应。

1 个答案:

答案 0 :(得分:4)

如果您有一个索引列表,用于指定向量中的异常值位置,例如使用:

out_idx = which(df$value > quan0.99)

您可以执行以下操作:

for(idx in out_idx) {
  vec[(idx-1):(idx+1)] = mean(vec[(idx-1):(idx+1)])
}

您可以将其包装在一个函数中,使bandwith和函数成为可选参数:

average_outliers = function(vec, outlier_idx, bandwith, func = "mean") {
   # iterate over outliers
   for(idx in out_idx) {
    # slicing of arrays can be used for extracting information, or in this case,
    # for assiging values to that slice. do.call is used to call the e.g. the mean 
    # function with the vector as input.
    vec[(idx-bandwith):(idx+bandwith)] = do.call(func, out_idx[(idx-bandwith):(idx+bandwith)])
  }      
  return(vec)
}

允许您同时使用带宽为2的median。使用此功能:

# Call average_outliers multiple times on itself,
# first for the 0.99 quantile, then for the 0.01 quantile.
vec = average_outliers(vec, which(vec > quan0.99))
vec = average_outliers(vec, which(vec < quan0.01))

或:

vec = average_outliers(vec, which(vec > quan0.99), bandwith = 2, func = "median")
vec = average_outliers(vec, which(vec < quan0.01), bandwith = 2, func = "median")

使用带宽为2,并用中值替换。