Удалите выбросы полностью из нескольких boxplots, сделанных с ggplot2 в R, и отобразите boxplots в расширенном формате
у меня есть некоторые сведения здесь [in a .txt-файл] который я прочитал в фрейме данных df,
df <- read.table("data.txt", header=T,sep="t")
Я удаляю отрицательные значения в столбце x (так как мне нужны только положительные значения)df используя следующий код
yp <- subset(df, x>0)
теперь я хочу построить несколько графиков в одном слое. Я сначала плавлю фрейм данных df, и график, результаты которого содержат несколько выбросов, как показано под.
# Melting data frame df
df_mlt <-melt(df, id=names(df)[1])
# plotting the boxplots
plt_wool <- ggplot(subset(df_mlt, value > 0), aes(x=ID1,y=value)) +
geom_boxplot(aes(color=factor(ID1))) +
scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x))) +
theme_bw() +
theme(legend.text=element_text(size=14), legend.title=element_text(size=14))+
theme(axis.text=element_text(size=20)) +
theme(axis.title=element_text(size=20,face="bold")) +
labs(x = "x", y = "y",colour="legend" ) +
annotation_logticks(sides = "rl") +
theme(panel.grid.minor = element_blank()) +
guides(title.hjust=0.5) +
theme(plot.margin=unit(c(0,1,0,0),"mm"))
plt_wool

теперь мне нужно иметь сюжет без каких-либо выбросов, поэтому для этого сначала я вычисляю нижнюю и верхнюю границы усов я использую следующий код, как было предложено здесь,
sts <- boxplot.stats(yp$x)$stats
чтобы удалить выброс, я добавляю верхний и нижний пределы усов, как показано ниже,
p1 = plt_wool + coord_cartesian(ylim = c(sts*1.05,sts/1.05))
результирующий график показан ниже, в то время как вышеуказанная строка кода правильно удаляет большинство верхних выбросов все нижние выбросы все еще оставаться. Может кто-нибудь, пожалуйста, предложит, как полностью удалить все выбросы из этого сюжета, спасибо.

5 ответов
минимальный воспроизводимый пример:
library(ggplot2)
p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_boxplot()
не планируя выбросы:
p + geom_boxplot(outlier.shape=NA)
#Warning message:
#Removed 3 rows containing missing values (geom_point).
(Я предпочитаю получать это предупреждение, потому что через год с длинным сценарием это напомнило бы мне, что я сделал там что-то особенное. Если вы хотите избежать этого, используйте решение Sven.)
основываясь на предложениях @Sven Hohenstein, @Roland и @lukeA, я решил проблему отображения нескольких boxplots в расширенной форме без выбросов.
сначала постройте графики без выбросов, используя outlier.colour=NA на geom_boxplot()
plt_wool <- ggplot(subset(df_mlt, value > 0), aes(x=ID1,y=value)) +
geom_boxplot(aes(color=factor(ID1)),outlier.colour = NA) +
scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x))) +
theme_bw() +
theme(legend.text=element_text(size=14), legend.title=element_text(size=14))+
theme(axis.text=element_text(size=20)) +
theme(axis.title=element_text(size=20,face="bold")) +
labs(x = "x", y = "y",colour="legend" ) +
annotation_logticks(sides = "rl") +
theme(panel.grid.minor = element_blank()) +
guides(title.hjust=0.5) +
theme(plot.margin=unit(c(0,1,0,0),"mm"))
затем вычислите нижние, верхние усы, используя boxplot.stats() как ниже код. Поскольку я учитываю только положительные значения, я выбираю их, используя условие в subset().
yp <- subset(df, x>0) # Choosing only +ve values in col x
sts <- boxplot.stats(yp$x)$stats # Compute lower and upper whisker limits
теперь, чтобы достичь полный расширенный вид нескольких boxplots, полезно изменить предел оси y участка внутри coord_cartesian() функции как ниже
p1 = plt_wool + coord_cartesian(ylim = c(sts[2]/2,max(sts)*1.05))
Примечание: пределы y должны быть отрегулированы в соответствии с конкретным случаем. В этом случае я выбрал половину нижнего предела усов для ymin.
результирующий участок ниже,

вы можете сделать выбросы невидимыми с аргументом outlier.colour = NA:
geom_boxplot(aes(color = factor(ID1)), outlier.colour = NA)
ggplot(df_mlt, aes(x = ID1, y = value)) +
geom_boxplot(outlier.size = NA) +
coord_cartesian(ylim = range(boxplot(df_mlt$value, plot=FALSE)$stats)*c(.9, 1.1))
другой способ исключить выбросы-вычислить их, а затем установить y-лимит на то, что вы считаете выбросом.
например, если верхний и нижний пределы Q3 + 1.5 IQR и Q1 - 1.5 IQR, тогда вы можете использовать:
upper.limit <- quantile(x)[4] + 1.5*IQR(x)
lower.limit <- quantile(x)[2] - 1.5*IQR(x)
затем поместите ограничения на диапазон оси y:
ggplot + coord_cartesian(ylim=c(lower.limit, upper.limit))