删除异常值并适当减少 ggplot2 中每个方面的 yLim

Remove outliers and reduce yLim appropriately for each facet in ggplot2

我目前正在使用 ggplot2 制作多面箱形图,我已清除异常值并将 yLim 设置为 5000。

然而,并不是所有的箱线图(下图开头的箱线图)都接近 5000。我怎样才能减少图中 select 少数这些箱线图的 y 轴?我已经尝试了来自社区的多个答案,但它们似乎已经过时了。

这是我使用的代码:

require(reshape2)
require(ggplot2)

data_frame <- read.csv("results.csv", header=T)

p <- ggplot(data=data_frame, aes(x='', y=value)) + geom_boxplot(outlier.shape=NA, aes(fill=policy))
p <- p + facet_wrap( ~ level, scales="free") + coord_cartesian(ylim = c(0, 5000))
p <- p + xlab("") + ylab("Authorisation Time (ms)") + ggtitle("Title")
ggsave("bplots.png", plot=last_plot(), device=png())

如上所述,您几乎必须在绘图之前进行过滤,但这不需要通过编辑任何文件甚至创建新的数据帧来完成。使用 dplyr 您可以将其链接到数据处理中。我在下面用一些虚构的数据做了一个有望重现的例子(因为我没有你的数据)。我创建了一个函数来按照箱线图使用的相同程序进行过滤。这有点老套,但希望能作为一种潜在的解决方案:

require(ggplot2)
require(dplyr)

data_frame <- data.frame(value = c(rnorm(2000, mean = 100, sd = 20), rnorm(2000, mean = 1000, sd = 500)),
           level = c(rep(1,2000), rep(2, 2000)),
           policy = factor(c(rep(c(rep(1, 500), rep(2, 500), rep(3, 500), rep(4, 500)), 2))))

# filtering function - turns outliers into NAs to be removed
filter_lims <- function(x){
  l <- boxplot.stats(x)$stats[1]
  u <- boxplot.stats(x)$stats[5]

  for (i in 1:length(x)){
    x[i] <- ifelse(x[i]>l & x[i]<u, x[i], NA)
  }
  return(x)
}

data_frame %>% 
  group_by(level, policy) %>%  # do the same calcs for each box
  mutate(value2 = filter_lims(value)) %>%  # new variable (value2) so as not to displace first one)
  ggplot(aes(x='', y=value2, fill = policy)) + 
  geom_boxplot(na.rm = TRUE, coef = 5) +  # remove NAs, and set the whisker length to all included points
  facet_wrap( ~ level, scales="free") + 
  xlab("") + ylab("Authorisation Time (ms)") + ggtitle("Title")

产生以下(简化的)图: