【问题标题】:Problem related to outliers removal from a dataset (R)与从数据集中移除异常值相关的问题 (R)
【发布时间】:2019-05-07 07:55:39
【问题描述】:

我在 R 中创建的函数有一些问题(我是这种语言的初学者)。这是一个删除数据集中异常值的函数:

removalOutlier <- function(data){
  q1 <- 0
  q2 <- 0
  q3 <- 0

 for(j in 1:(ncol(data)-1)){
   m <- length(data[,j])

   J<-0
   data<-data[order(data[,j]),]
   data<-as.matrix(data)
   print(data)
   q2 <- median(data[,j])

if((m %% 2) != 0){     
  q1 <- median(data[1:(((m+1)/2)-1),j]) #m dispari
  q3 <- median(data[(((m+1)/2)+1):m,j])
   } else {  
   q1 <- median(data[1:(m/2),j]) #m pari
   q3 <- median(data[(m+2)/2:m,j])     
  }

    iqr = q3-q1

    for(k in 1:(length(data[,j]))){
    print(data[k,j])

    if((data[k,j] > (q3+(1.5*iqr))) | (data[k,j] < (q1-(1.5*iqr))))

    {
     J[k]<-k
     data <- as.matrix(data) 
     }
     else 
     {J[k]<-0}        
   }

 data <- as.data.frame(data)

  for(z in 1:length(J)){
    if(J[z]!=0){

    data<-data.frame(data[-J[z],])
    } 
  }
 print (data)

}
data 
}

这是与数据集第一列相关的有序输出。将数据集的第一列分成四分位数,我发现:Q1-1.5*IQR=117 和 Q3+1.5*IQR=3609。由于我有这些结果,函数应该删除以下列表的最后三个样本:

     V1 V2     V3
45  852  2 179900
32 1000  1 169900
26 1100  3 249900
44 1200  3 299000
47 1203  3 239500
18 1236  3 199900
37 1239  3 229900
15 1268  3 259900
17 1320  2 299900
9  1380  3 212000
4  1416  2 232000
8  1427  3 198999
36 1437  3 249900
27 1458  3 464500
10 1494  3 242500
7  1534  3 314900
2  1600  3 329900
23 1604  3 242900
41 1664  2 368500
21 1767  3 252900
35 1811  4 285900
31 1839  2 349900
46 1852  4 299900
22 1888  2 255000
13 1890  3 329999
11 1940  4 239999
24 1962  4 259900
6  1985  4 299900
12 2000  3 347000
33 2040  4 314900
1  2104  3 399900
38 2132  4 345000
40 2162  4 287000
29 2200  3 475000
42 2238  3 329900
16 2300  4 449900
3  2400  3 369000
28 2526  3 469000
43 2567  4 314000
19 2609  4 499998
30 2637  3 299900
5  3000  4 539900
20 3031  4 599000
34 3137  3 579900
25 3890  3 573900
14 4478  5 699900
39 4515  4 549000

但它会删除:

25 3890  3 573900
39 4515  4 549000

而不是:

14 4478  5 699900

我不明白为什么。当我通过检查第二列中是否存在异常值时,我找到它们并毫无问题地删除它们。

【问题讨论】:

  • 乍一看,我不确定您的代码有什么问题。一般来说,我建议您寻找内置函数来执行看起来像是常见任务的事情,而不是编写自己的代码。这些功能已经过很好的测试,在您自己的时间和运行时都将更加高效。例如,如果您搜索“iqr in R”,您会很快找到 IQR() 函数,它可以替换您的许多代码行。
  • 您能否通过dput 函数提供示例数据。尽管值得注意的 advances in that field,但将数据帧从 SO 快速复制/粘贴到 R 仍然很痛苦。
  • 看看这个问题,同样的问题,但使用箱线图功能来执行工作。 stackoverflow.com/questions/53201016/…

标签: r machine-learning outliers


【解决方案1】:

此代码将根据您的 IQR 逻辑删除最后 3 行

bound <- quantile(df$V1, c(.25, .75)) + c(-1, 1)*1.5*IQR(df$V1)
out <- subset(df, V1 > bound[1] & V1 < bound[2])

检查结果:

nrow(df) - nrow(out)
# [1] 3

data.table::fsetdiff(df, out)
#      V1 V2     V3
# 1: 3890  3 573900
# 2: 4478  5 699900
# 3: 4515  4 549000

使用的数据:

df <- data.table::fread('
     V1 V2     V3
45  852  2 179900
32 1000  1 169900
26 1100  3 249900
44 1200  3 299000
47 1203  3 239500
18 1236  3 199900
37 1239  3 229900
15 1268  3 259900
17 1320  2 299900
9  1380  3 212000
4  1416  2 232000
8  1427  3 198999
36 1437  3 249900
27 1458  3 464500
10 1494  3 242500
7  1534  3 314900
2  1600  3 329900
23 1604  3 242900
41 1664  2 368500
21 1767  3 252900
35 1811  4 285900
31 1839  2 349900
46 1852  4 299900
22 1888  2 255000
13 1890  3 329999
11 1940  4 239999
24 1962  4 259900
6  1985  4 299900
12 2000  3 347000
33 2040  4 314900
1  2104  3 399900
38 2132  4 345000
40 2162  4 287000
29 2200  3 475000
42 2238  3 329900
16 2300  4 449900
3  2400  3 369000
28 2526  3 469000
43 2567  4 314000
19 2609  4 499998
30 2637  3 299900
5  3000  4 539900
20 3031  4 599000
34 3137  3 579900
25 3890  3 573900
14 4478  5 699900
39 4515  4 549000
')[, -1]

【讨论】:

    【解决方案2】:

    以下函数根据问题的标准删除异常值,但结果与 OP 的结果不同。

    removalOutlier2 <- function(data){
      f <- function(x){
        iqr <- IQR(x, na.rm = TRUE)
        qq <- quantile(x, c(1, 3)/4)
        lims <- qq + c(-1, 1)*1.5*iqr
        out <- which(x < lims[1] | lims[2] < x)
        x[out] <- median(x, na.rm = TRUE)
        x
      }
      data[] <- lapply(data, f)
      data
    }
    
    df2 <- removalOutlier2(data)
    

    编辑。

    函数的结果与answer by IceCreamToucan中的结果一致。

    【讨论】:

      猜你喜欢
      • 2015-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 2012-10-02
      • 2011-06-07
      • 2018-05-09
      相关资源
      最近更新 更多