Я хочу построить гистограмму некоторых данных. Данные содержат некоторые экстремальные значения или выбросы, поэтому я хотел бы исключить их из графика, чтобы получить значимое представление об основной массе данных. Вот несколько примеров данных:
x <- c(seq(0, 1, 0.05)^2, 5)
hist(x)
Вы не можете ничего увидеть о распределении из-за одного выброса. Я мог просто вручную исключить выбросы.
hist(x[x<2])
По сути, это то, что я хочу, но это требует от меня определения точного отсечения, и это неудобно, если данные представляют собой не просто x, а какое-то сложное выражение. Я бы предпочел указать hist, чтобы он обрезал несколько самых больших и самых маленьких процентов данных, аналогично параметру обрезки в функции mean.
Я мог бы также вручную установить xlim и перерывы, но это еще более неудобно.
Есть ли хороший способ удалить самые экстремальные значения перед построением графика?
Возможно, напишем функцию обрезки. Эта функция удаляет выбросы, которые определяются как превышающие 1,5-кратный межквартильный размах от среднего. (Это определение выброса, используемое коробчатыми диаграммами Тьюки.)
trim <- function(x){
x[(x > mean(x)-1.5*IQR(x)) & (x < mean(x)+1.5*IQR(x))]
}
hist(trim(x))
Или выполните обрезку по процентилю.
trim_q <- function(x, lb, ub){
x[(x > quantile(x, lb)) & (x < quantile(x, ub))]
}
hist(trim_q(x, 0.01, 0.99))
Это усекает данные между первым и девяносто девятым процентилем.
Первая функция обрезки не совсем правильная. Я думаю, что Тьюки определил его как 1,5-кратный межквартильный размах выше и ниже первого и третьего квартилей, а не среднее значение, как я сделал здесь. Должно получиться так:
trim_t <- function(x){
x[(x > quantile(x, 0.25)-1.5*IQR(x)) & (x < quantile(x, 0.75)+1.5*IQR(x))]
}
hist(trim_t(x))
Я знаю, что это не совсем то, о чем вы просили, но если вы хотите буквально обрезать гистограмму, вы можете это сделать. В данном случае я убираю два самых крайних бункера. Вы, конечно, можете обрезать по многим другим правилам.
set.seed(1)
x <- rnorm(40)^3
x <- round(x, 1)*10
par(mfrow=c(2, 1), mar=c(3, 3, 0.1, 1))
h <- hist(x, main = "")
h[1:4] <- lapply(h[1:4], function(y) head(y[-1], -1))
plot(h, main = "")
Написание небольшой функции обрезки, вероятно, лучший способ. Таким образом, я мог бы также использовать его для других графиков или анализа данных. Спасибо.