R 在任何列中查找具有异常值的行

R 在任何列中查找具有异常值的行,r,dataframe,outliers,R,Dataframe,Outliers,给定dataframe df中的如下数据,需要提取任何列都有异常值的行 text = " A,B,C,D,E,F,G 93,53,221,314,104,721,179 100,58,218,318,93,718,181 601,61,228,829,106,739,190 510,60,229,739,95,707,181 779,51,242,1021,105,756,180 848,57,228,1076,93,710,191 94,52,227,321,95,723,179 712,58

给定dataframe df中的如下数据,需要提取任何列都有异常值的行

text = "
A,B,C,D,E,F,G
93,53,221,314,104,721,179
100,58,218,318,93,718,181
601,61,228,829,106,739,190
510,60,229,739,95,707,181
779,51,242,1021,105,756,180
848,57,228,1076,93,710,191
94,52,227,321,95,723,179
712,58,242,954,486,750,180
,53,,10289,298,841,210
696,53,233,929,95,751,180
101,57,220,321,415,796,179
100,60,226,326,104,744,180
181,58,234,415,105,2870,468
,57,,10277,,,918
"
df = read.table(textConnection(text), sep=",", header = T)
异常值定义为箱线图-Q1-1.5IQR/Q3+1.5IQR。因此,任何列(一个或多个)具有该列的异常值的行都将在我们的输出集中

我们还想得到第二组行,其中任何列值仅高于Q3+1.5IQR值的行将位于我们的输出集中,而不是上面经典定义中的异常值

我面临着一些挑战要完成这件事。我正在思考的伪代码如下

  • 计算每列的箱线图统计信息
  • 使用Q1和Q3值获得列值大于Q3且小于Q1的行索引
  • 关于#1,我尝试了以下方法

    > sapply(df, boxplot.stats)
          A         B         C         D         E         F         G        
    stats Numeric,5 Numeric,5 Numeric,5 Numeric,5 Numeric,5 Numeric,5 Numeric,5
    n     12        14        12        14        13        13        14       
    conf  Numeric,2 Numeric,2 Numeric,2 Numeric,2 Numeric,2 Numeric,2 Numeric,2
    out   Integer,0 Integer,0 Integer,0 Integer,2 Integer,3 Integer,2 Integer,3
    
    但这并没有给出像
    stats这样的输出
    
    长度为5的向量,包含下须的极值、下‘铰链’、中位数、上‘铰链’和上须的极值。
    可以在#2中使用。

    我们可以编写一个函数来确定该值是否为异常值

    IsOutlier <- function(data) {
       lowerq = quantile(data, na.rm = TRUE)[2]
       upperq = quantile(data, na.rm = TRUE)[4]
       iqr = upperq - lowerq 
       threshold_upper = (iqr * 1.5) + upperq
       threshold_lower = lowerq - (iqr * 1.5)
       data > threshold_upper | data <  threshold_lower 
    }
    

    同样,对于第二个集合,我们可以使用这个函数

    IsOutlier_upper <- function(data) {
       upperq = quantile(data, na.rm = TRUE)[4]
       lowerq = quantile(data, na.rm = TRUE)[2]
       iqr = upperq - lowerq 
       data > (upperq + 1.5 * iqr) 
    }
    
    IsOutlier\u upper(upperq+1.5*iqr)
    }
    
    到目前为止,您尝试了什么?您是否被困在某个特定的地方?使用您在此处提供的数据非常困难,没有工具(我知道)以本机方式读取这些数据(并返回一个R友好对象)。你会考虑做两件事吗?(1) 使用
    dput(head(x))
    data.frame(…)
    (或类似的编程方式)提供示例数据;(2)对于(比如)10行数据是否也能产生同样的效果?(3)
    A
    (时间)与这些有什么关系?不要给我们提供与你的问题无关的东西也有帮助。最后,正如RAB所建议的,(4)请显示您迄今为止尝试过的代码,它将帮助指导编码风格,等等。@r2evans-更新了问题。如果您查看一次调用的输出,
    boxplot.stats
    将返回一个
    列表
    ,而返回的值实际上被宣传为“包含以下命名组件的列表”。你可以做一些像sappy(df,function(x)boxplot.stats(x)$stats)这样的事情来获得更有用的东西。
    >sappy(df,function(x)boxplot.stats(x)$stats(x)$stats)A B C D E F G[1,]93.051218.0314 93 707 179.0[2,]100.053 223.5 321 95 721 180.0[3,]345.5 57 228.0 784 104 744 180.5[4,]704.0 58 233.5 1021 106 756 191.0[5,]848.0 61 242.0 1076 106 796 191.0
    -我们如何从中访问
    上须
    IsOutlier_upper <- function(data) {
       upperq = quantile(data, na.rm = TRUE)[4]
       lowerq = quantile(data, na.rm = TRUE)[2]
       iqr = upperq - lowerq 
       data > (upperq + 1.5 * iqr) 
    }