在任何列中查找具有离群值的行
find rows with outlier values in any columns
给定如下数据框 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
a vector of length 5, containing the extreme of the lower whisker, the lower ‘hinge’, the median, the upper ‘hinge’ and the extreme of the upper whisker.
这样的输出,而这本可以在 #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
}
和 select 行至少有一个异常值
df[rowSums(sapply(df, IsOutlier), na.rm = TRUE) > 0, ]
# A B C D E F G
#8 712 58 242 954 486 750 180
#9 NA 53 NA 10289 298 841 210
#11 101 57 220 321 415 796 179
#13 181 58 234 415 105 2870 468
#14 NA 57 NA 10277 NA NA 918
同样,对于第二组我们可以使用这个函数
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)
}
给定如下数据框 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
a vector of length 5, containing the extreme of the lower whisker, the lower ‘hinge’, the median, the upper ‘hinge’ and the extreme of the upper whisker.
这样的输出,而这本可以在 #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
}
和 select 行至少有一个异常值
df[rowSums(sapply(df, IsOutlier), na.rm = TRUE) > 0, ]
# A B C D E F G
#8 712 58 242 954 486 750 180
#9 NA 53 NA 10289 298 841 210
#11 101 57 220 321 415 796 179
#13 181 58 234 415 105 2870 468
#14 NA 57 NA 10277 NA NA 918
同样,对于第二组我们可以使用这个函数
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)
}