Я рекомендую использовать функцию boxplot()
-, которая вычисляет выбросы. Вы можете получить к ним доступ в вашем boxplot
-объекте через boxplot$out
или получить квантили через boxplot$stats
. Что я и делаю дальше.
Но имейте в виду, что блокпост не рассчитывает выбросы с точки зрения 3 стандартных отклонений, а с Q1 - 1.5*IQR
и Q3 + 1.5*IQR
соответственно.
library(dplyr) # for the pipe operators
#creating sample data
df <- data.frame("var1" = c(-20.32, -15.29, rnorm(5,1,1), 11.23, 20.45),
"var2" = c(-12.43, -3.12, rnorm(5, 1,1), 10.75, 18.11))
#looks like that
> df
var1 var2
1 -20.3200000 -12.4300000
2 -15.2900000 -3.1200000
3 0.9950276 1.2645415
4 1.7022687 0.8313770
5 1.8828154 -0.7459769
6 1.2299670 0.5053378
7 0.2749259 2.0239793
8 11.2300000 10.7500000
9 20.4500000 18.1100000
#remove outliers
nooutliers <- lapply(df, function(x) boxplot(df, plot = FALSE)) %>%
lapply(`[`, "stats") %>%
lapply(range) %>%
mapply(function (x,y) !between(x, y[1], y[2]), df, .) %>%
as.data.frame %>%
mapply(function(x,y) {y[x] <- NA; y},
y = df, x = .)
#looks like this now
> nooutliers
var1 var2
[1,] NA NA
[2,] NA -3.1200000
[3,] 0.9950276 1.2645415
[4,] 1.7022687 0.8313770
[5,] 1.8828154 -0.7459769
[6,] 1.2299670 0.5053378
[7,] 0.2749259 2.0239793
[8,] NA NA
[9,] NA NA
Этот код вычисляет диапазон в пределах усов для каждого столбца, присваивает NA
всем значениям за пределами этого диапазона и возвращает матрицу.
Полагаю, это то, что вы ищете.
ОБНОВЛЕНИЕ: с 3 стандартными отклонениями:
df <- data.frame("var1" = c(-210.32, rnorm(20,1,1), 234.45),
"var2" = c(-230.43, rnorm(20, 1,1), 213.11))
phenotypes <- colnames(df)
for (i in phenotypes){
Min <- mean(df[[i]]) - (3*sd(df[[i]]))
Max <- mean(df[[i]]) + (3*sd(df[[i]]))
df[[i]][df[[i]] < Min | df[[i]] > Max] <- NA}
Это принимает ваше определение выброса.