【问题标题】:Using a repeat loop to look for multiple outliers?使用重复循环查找多个异常值?
【发布时间】:2023-03-15 18:42:02
【问题描述】:

我对 R 很陌生,并且正在为重复循环、寻找异常值或两者兼而有之而苦苦挣扎。

我有一个矩阵形式的大型但不可靠的数据集。我正在使用包异常值来搜索数据集中的异常值,特别是在我的数据矩阵的每一行中,但是每一行都有多个异常值。为了查找多个异常值,我尝试使用重复循环替换异常值(使用行平均值),直到行的标准偏差低于某个指定值。

replaceoutliers <- function(data, standarddeviationthreshold) {
for(k in 1:nrow(data)) {
    repeat{
        data[k,] <- rm.outlier(data[k,], fill=TRUE, median=FALSE, opposite=FALSE)
            if(sd(data[k,]) > standarddeviationthreshold) {
            break
          }
        }
    }
    View(data)
}

函数运行,但只替换每一行中的高值。重复循环有问题吗?有谁知道可以找到并替换多个异常值的包?到目前为止,我一直无法罚款。

谢谢!

编辑:我无法共享我正在使用的数据,但这是我运行的测试: 我通过了函数

data <- matrix(c(1:16)^2, nrow=4, ncol=4)
data
         [,1] [,2] [,3] [,4]
[1,]    1   25   81  169
[2,]    4   36  100  196
[3,]    9   49  121  225
[4,]   16   64  144  256

replaceoutliers(data, 1)
     [,1] [,2] [,3]     [,4]
[1,]    1   25   81 35.66667
[2,]    4   36  100 46.66667
[3,]    9   49  121 59.66667
[4,]   16   64  144 74.66667

所以我们看到高值被平均值所取代。但是,例如,在第一行中,也应该替换 1。

【问题讨论】:

  • 正常是​​数据。忘记改了,抱歉。
  • 显然,rm.outlier(..., fill=TRUE) 是幂等的。
  • 所以,如果我改变了我用来识别异常值的方法,我应该可以去吗?

标签: r outliers


【解决方案1】:

你最好直接使用outlier函数,依次去除异常值:

replaceoutliers <- function(x, threshold) {
  t(apply(data, 1, function(row) {
    exclude <- rep(FALSE, length(row))
    repeat {
      outliers <- outlier(row[!exclude], logical=TRUE)
      exclude[!exclude] <- outliers
      if (sd(row[!exclude]) < threshold) break
    }
    row[exclude] <- mean(row)
    row
  }))
}

在这里,异常值被连续从数据中删除并替换为平均值,直到超出所需的标准偏差。

一些注意事项:

标准差检验的方向错误。当您用平均值替换异常值时,标准差会减小。

outlier 在数据中找到一个异常值,即更差的值。为删除的值保持逻辑允许在跟踪数据位置的同时连续删除。

无法保证在第二次迭代时会删除较低的值。对于第一行,您将在删除 1 之前删除 81

如果您尝试的标准差过低,则测试会失败。可以为此编写一个守卫,但我没有:

> replaceoutliers(data, 50)
     [,1] [,2] [,3] [,4]
[1,]    1   25   81   69
[2,]    4   36  100   84
[3,]    9   49  101  101
[4,]   16   64  120  120
> replaceoutliers(data, 34)
     [,1] [,2] [,3] [,4]
[1,]    1   25   69   69
[2,]    4   36   84   84
[3,]    9   49  101  101
[4,]   16   64  120  120
> replaceoutliers(data, 33)
 Error in if (sd(row[!exclude]) < threshold) break : 
  missing value where TRUE/FALSE needed 

【讨论】:

    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 2019-12-05
    • 2019-03-28
    • 2022-08-13
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 2013-05-13
    相关资源
    最近更新 更多