ggplot2 在使用自定义 x 轴限制绘制直方图时丢失数据

cha*_*h_7 2 r ggplot2

我试图用这些数据绘制六个直方图(2 列数据(卡路里、钠)x 3 种类型(牛肉、肉类、家禽)) ,我想为它们提供相同的 x 和 y 轴比例。我用来scale_x_continuous限制 x 轴,根据各种来源,它会删除不会出现在绘图上的数据。这是我的代码:

#src.table is the data frame containing my data
histogram <- function(df, dataset, n_bins, label) {
  ggplot(df, aes(x=df[[dataset]])) + 
  geom_histogram(color="darkblue", fill="lightblue", bins = n_bins) + xlab(label)
}
src2_12.beef <- src2_12.table[src2_12.table$Type == "Beef",]
src2_12.meat <- src2_12.table[src2_12.table$Type == "Meat",]
src2_12.poultry <- src2_12.table[src2_12.table$Type == "Poultry",]

src2_12.calories_scale <- lims(x = c(min(src2_12.table$Calories), max(src2_12.table$Calories)), y = c(0, 6))
src2_12.sodium_scale <- lims(x = c(min(src2_12.table$Sodium), max(src2_12.table$Sodium)), y = c(0, 6)) 
#src2_12.calories_scale <- lims()
#src2_12.sodium_scale <- lims()

src2_12.plots <- list(
  histogram(src2_12.beef, "Calories", 10, "Calories-Beef") + src2_12.calories_scale,
  histogram(src2_12.meat, "Calories", 10, "Calories-Meat") + src2_12.calories_scale,
  histogram(src2_12.poultry, "Calories", 10, "Calories-Poultry") + src2_12.calories_scale,
  histogram(src2_12.beef, "Sodium", 10, "Sodium-Beef") + src2_12.sodium_scale,
  histogram(src2_12.meat, "Sodium", 10, "Sodium-Meat") + src2_12.sodium_scale,
  histogram(src2_12.poultry, "Sodium", 10, "Sodium-Poultry") + src2_12.sodium_scale
  )
multiplot(plotlist = src2_12.plots, cols = 2, layout = matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, byrow = TRUE))
Run Code Online (Sandbox Code Playgroud)

这是输出: 输出

与数据应有的样子: 在此输入图像描述

我无法理解为什么缺少一些数据点,因为我设置的限制已经是数据的最小值和最大值。

jor*_*ran 5

您可能想使用coord_cartesian而不是lims. 当您摆弄直方图的限制时,可能会发生意想不到的事情,因为从原始数据到实际直方图必须进行相当多的复杂转换。

让我们深入了解一个例子:

p <- ggplot(src2_12.beef,aes(x = Calories)) + 
  geom_histogram(bins = 10)
p1 <- ggplot(src2_12.beef,aes(x = Calories)) + 
  geom_histogram(bins = 10) + 
  lims(x = c(86,195))

a <- ggplot_build(p)
b <- ggplot_build(p1)

>a$data[[1]][,1:5]
   y count        x     xmin     xmax
1  1     1 114.1111 109.7222 118.5000
2  0     0 122.8889 118.5000 127.2778
3  3     3 131.6667 127.2778 136.0556
4  2     2 140.4444 136.0556 144.8333
5  5     5 149.2222 144.8333 153.6111
6  2     2 158.0000 153.6111 162.3889
7  0     0 166.7778 162.3889 171.1667
8  2     2 175.5556 171.1667 179.9444
9  3     3 184.3333 179.9444 188.7222
10 2     2 193.1111 188.7222 197.5000

> b$data[[1]][,1:5]
   y count         x      xmin      xmax
1  0     0        NA        NA  90.83333
2  0     0  96.88889  90.83333 102.94444
3  1     1 109.00000 102.94444 115.05556
4  0     0 121.11111 115.05556 127.16667
5  4     4 133.22222 127.16667 139.27778
6  4     4 145.33333 139.27778 151.38889
7  4     4 157.44444 151.38889 163.50000
8  1     1 169.55556 163.50000 175.61111
9  4     4 181.66667 175.61111 187.72222
10 2     2 193.77778 187.72222        NA
> 
Run Code Online (Sandbox Code Playgroud)

所以现在你想知道这到底是怎么发生的,对吧?

好吧,当您告诉 ggplot 您需要 10 个 bin 并且 x 限制从 86 到 195 时,直方图算法会尝试创建跨越该实际范围的 10 个 bin。这就是为什么它尝试创建低于 100 个的 bin,即使那里没有数据。

然后可能会发生更多奇怪的情况,因为条形可能会超出标称数据范围(xminxmax值),因为条形宽度通常会略高于和略低于实际数据的高端和低端。

coord_cartesian将在所有这些处理发生调整 x 限制,因此它绕过了所有这些小怪癖。