当绘制具有自定义x轴限制的直方图时,ggplot2缺少数据

时间:2017-09-07 22:09:03

标签: r ggplot2

我试图用these data绘制六个直方图(2列数据(卡路里,钠)×3种类型(牛肉,肉类,家禽))并且我想给它们相同的x和y比例轴。我正在使用scale_x_continuous来限制x轴,根据各种来源,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))

这是输出: output

VS。数据应该是什么样的: enter image description here

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

1 个答案:

答案 0 :(得分:3)

您可能希望使用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
> 

所以现在你想知道发生了什么

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

然后会发生更多奇怪的事情,因为 bar 可能会延伸超过标称数据范围(xminxmax值),因为条形宽度通常会包含一个比高端和低端的实际数据略高一点。

coord_cartesian将在
所有这些处理完成后调整x限制,因此它会绕过所有这些小怪癖。