首页 > 解决方案 > 如何根据数量更改ggplot中每个方面的xlim或比例?

问题描述

library(tidyr)
library(ggplot2)

df <- data.frame(a = as.numeric(c(1, 2, 3, 4, 5, 6)), 
                 b = as.numeric(c(1, 3, 3, 5, 10, 1000)),
                 c = as.numeric(c(0.07, 0.09, 6, 9, 10, 30)))

ggplot(gather(na.omit(df)), aes(x = value, y = ..density..))+
    geom_histogram(bins = 5, colour = "black", fill = "white") +
    facet_wrap(~key, scales = 'free_x')+
    scale_x_continuous(breaks = scales::pretty_breaks(5))+
    geom_density(alpha = .2, fill = "#FF6666")

上述脚本的输出如下:

在此处输入图像描述

至于有1000, 0.07 in等异常值df, 尺度 x 被拉伸, 使密度线不可见。

有没有办法按比例进行子集facetquantile(facet,c(0.01,0.99)),或xlim = quantile(facet, c(0.01,0.99))排除规模上的异常值?

标签: rggplot2

解决方案


您可以在sapply.

df2 <- as.data.frame(sapply(df1, function(x){
  qu <- quantile(x, c(0.01, 0.99))
  x[which(x > qu[1] & x < qu[2])]}))
df2
#   a  b     c
# 1 2  3  0.09
# 2 3  3  6.00
# 3 4  5  9.00
# 4 5 10 10.00

或者,使用data.table::between,这对间隔很有用。

library(data.table)
df2 <- as.data.frame(sapply(df1, function(x)
  x[which(x %between% quantile(x, c(0.01, 0.99)))]))
df2
#   a  b     c
# 1 2  3  0.09
# 2 3  3  6.00
# 3 4  5  9.00
# 4 5 10 10.00

然后只需使用您的旧代码。我对其进行了一些调整,而是stack在此处使用 base R,它的作用与gather避免加载过多的附加包相同。

library(ggplot2)
ggplot(stack(na.omit(df2)), aes(x=values, y=..density..)) +
  geom_histogram(bins=5, colour="black", fill="white") +
  facet_wrap(~ind, scales='free_x') +
  scale_x_continuous(breaks=scales::pretty_breaks(5)) +
  geom_density(alpha=.2, fill="#FF6666")

结果

在此处输入图像描述

数据

df1 <- structure(list(a = c(1, 2, 3, 4, 5, 6), b = c(1, 3, 3, 5, 10, 
1000), c = c(0.07, 0.09, 6, 9, 10, 30)), class = "data.frame", row.names = c(NA, 
-6L))

推荐阅读