Непосредственная попытка может использовать %in%
, что-то вроде
boxplot.stats(iris$Sepal.Width)
# $stats
# [1] 2.2 2.8 3.0 3.3 4.0
# $n
# [1] 150
# $conf
# [1] 2.935497 3.064503
# $out
# [1] 4.4 4.1 4.2 2.0
iris[ iris$Sepal.Width %in% boxplot.stats(iris$Sepal.Width)$out, ]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 16 5.7 4.4 1.5 0.4 setosa
# 33 5.2 4.1 1.5 0.1 setosa
# 34 5.5 4.2 1.4 0.2 setosa
# 61 5.0 2.0 3.5 1.0 versicolor
(или некоторый вариант dplyr
или data.table
).
Но пока я не могу найти пример, который доказывает мою точку зрения здесь , теоретически в R и других языках программирования, равенство с плавающей точкой трудно сделать хорошо (последовательно, то есть; это связано с R FAQ 7.31 и IEEE -754). Для этого нужно найти значения в пределах допуска . Это не должно быть трудно сделать в разумных пределах, но это, безусловно, больше кода, чем указано выше.
Но, возможно, лучшим способом было бы записать индексы непосредственно в boxplot.stats
и использовать их вместо чрезмерного проектирования , Да, это больше кода, но он также выполняет меньше работы и делает это так же, как boxplot.stats
.
boxplot.stats2 <- function (x, coef = 1.5, do.conf = TRUE, do.out = TRUE) {
if (coef < 0)
stop("'coef' must not be negative")
nna <- !is.na(x)
n <- sum(nna)
stats <- stats::fivenum(x, na.rm = TRUE)
iqr <- diff(stats[c(2, 4)])
if (coef == 0) {
do.out <- FALSE
} else {
out <-
if (!is.na(iqr)) {
x < (stats[2L] - coef * iqr) | x > (stats[4L] + coef * iqr)
} else !is.finite(x)
if (any(out[nna], na.rm = TRUE)) {
stats[c(1, 5)] <- range(x[!out], na.rm = TRUE)
}
}
conf <- if (do.conf) stats[3L] + c(-1.58, 1.58) * iqr/sqrt(n)
list(stats = stats, n = n, conf = conf,
out = if (do.out) x[out & nna] else numeric(),
out.ind = if (do.out) which(out) else integer()) ### NEW
}
(Единственное изменение в исходной функции boxplot.stats
- это добавление out.ind
в возвращаемом значении. Все, что нам нужно, уже включено.)
bp <- boxplot.stats2(iris$Sepal.Width)
bp
# $stats
# [1] 2.2 2.8 3.0 3.3 4.0
# $n
# [1] 150
# $conf
# [1] 2.935497 3.064503
# $out
# [1] 4.4 4.1 4.2 2.0
# $out.ind
# [1] 16 33 34 61
, и вы можете использовать $out.ind
напрямую (iris[bp$out.ind,]
).