Удалить выбросы полностью из нескольких ящиков, сделанных с помощью ggplot2 в R, и отобразить ящики в расширенном формате

У меня есть некоторые данные здесь [в .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

Boxplot with outliers

Теперь мне нужно иметь сюжет без каких-либо выбросов, поэтому для этого сначала я вычисляю нижние и верхние усы, я использую следующий код, предложенный здесь,

sts <- boxplot.stats(yp$x)$stats

Чтобы удалить outlier, я добавляю верхний и нижний пределы усов, как показано ниже,

p1 = plt_wool + coord_cartesian(ylim = c(sts*1.05,sts/1.05))

Результирующий график показан ниже, в то время как вышеприведенная строка кода правильно удаляет большинство верхних выбросов, все нижние выбросы все еще остаются. Может кто-нибудь, пожалуйста, предложите, как полностью удалить весь выброс из этого графика, спасибо.

enter image description here

Ответ 1

Основываясь на предложениях @Sven Hohenstein, @Roland и @lukeA, я решил проблему для отображения нескольких ящиков в расширенной форме без выбросов.

Сначала зарисуйте графические объекты без выбросов, используя 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

Теперь, чтобы получить полное расширенное представление о нескольких ящиках, полезно изменить предел оси y графика внутри функции coord_cartesian(), как показано ниже,

p1 = plt_wool + coord_cartesian(ylim = c(sts[2]/2,max(sts)*1.05))

Примечание: Пределы y должны быть скорректированы в соответствии с конкретным случаем. В этом случае я выбрал половину нижнего предела нити для ymin.

Полученный график ниже,

Ответ 2

Минимальный воспроизводимый пример:

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).

(Я предпочитаю получать это предупреждение, потому что через год с длинным script он напомнит мне, что я сделал что-то особенное там. Если вы хотите избежать использования решения Sven.)

Ответ 3

Вы можете сделать outliers невидимыми с аргументом outlier.colour = NA:

geom_boxplot(aes(color = factor(ID1)), outlier.colour = NA)

Ответ 4

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))

Ответ 5

Другой способ исключить выбросы - это вычислить их, а затем установить y-предел на то, что вы считаете outlier.

Например, если ваши верхние и нижние пределы 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))