14.7 条形图

条形图(bar chart,又名柱状图、方框图等)是一种显示数值变量7的自然方式,此数值变量通常被类别变量所分割开。在下例中,我们来看看宗教身份在美国各州的分布情况。阿拉斯加和夏威夷的数据没有包括在数据集中,可以删除这些记录:

7更确切地说,它们必须是可计数的,或带有长度,又或其他能与零值相对比的值。对于对数比例来说,使用条形图其范围可能会延长到负无穷。在这种情况下,你应该使用点图。

  1. ovm <- ovm[!(ovm$State %in% c("Alaska", "Hawaii")), ]

base系统中,条形图是使用barplot函数创建的。与plot函数一样,它也没有参数来指定一个数据框,所以我们需要把它置于with之内。barplot的第一个参数包含条形的长度。如果这是一个命名向量(如果你没有出错,而且是从一个数据框里取得数据,这不会发生),那么这些名称将用作条形图上的标签。否则,正如这里的做法,你需要通过传递一个名为names.arg的参数指定标签值。默认情况下,条形都是垂直的。但为了使州名更可读,我们希望使用水平的条形图,这可以通过指定horiz = TRUE生成。

要显示各州的全名,我们还要通过par函数来调整一些绘图参数。由于历史的原因,大多数参数名称都只采用缩写,而不是更可读的值,这样代码看起来就会相当简洁。在修改base绘图之前,最好先看看?par帮助页面。

las参数(即label axis style的缩写)将控制标签是水平还是垂直的、是平行还是垂直于轴的。对于水平来说,如果你设置las = 1,绘图通常会更具可读性。参数mar是一个长度为4的数值向量,它将分别给出绘图区下/左/上/右的边距宽度。我们真的很希望左手侧的边距宽一点,这样才能把州的名字都放进去。图14-42显示了以下代码的输出结果。

  1. par(las = 1, mar = c(3, 9, 1, 1))
  2. with(ovm, barplot(Catholic, names.arg = State, horiz = TRUE))

像这样简单的条形图看上去挺好,但更有意思的是如何将含有几个变量的条形图放到一起。我们可以通过绘制天主教、新教、无宗教者以及其他栏来可视化宗教的分化情况。为了绘制多个变量,我们必须将它们逐行分别放入一个矩阵中(rbind对此非常有用)。

这个矩阵的列名被用为条形的名字;如果没有列名,则须像上例一样使用names.arg来完成。默认情况下,图中每个变量的条形都彼此相邻,但由于我们正研究变量之间的分化情况,所以堆叠条形图更加合适。可以通过传递beside = FALSE参数实现这一点,如图14-43所。

  1. religions <- with(ovm, rbind(Catholic, Protestant, Non.religious, Other))
  2. colnames(religions) <- ovm$State
  3. par(las = 1, mar = c(3, 9, 1, 1))
  4. barplot(religions, horiz = TRUE, beside = FALSE)

图像说明文字

图14-42:使用base系统绘制的条形图

图像说明文字

图14-43:使用base系统绘制的堆积条形图

lattice中与barplot等效的函数是barchart,如图14-44所示。该公式接口与我们在散点图中所看到是一样的yvar ~ XVAR

  1. barchart(State ~ Catholic, ovm)

图像说明文字

图14-44:使用lattice系统绘制的条形图

把这个扩展到多个变量只需要调整一下公式,传递stack = TRUE即可绘制堆积的图形(见图14-45):

  1. barchart(
  2. State ~ Catholic + Protestant + Non.religious + Other,
  3. ovm,
  4. stack = TRUE
  5. )

图像说明文字

图14-45:使用lattice系统绘制的堆积条形图

为了复制此图形,ggplot2需要对数据作一些额外的工作。我们需要长表中的数据,所以必须首先对所需的列进行melt操作:

  1. religions_long <- melt(
  2. ovm,
  3. id.vars = "State",
  4. measure.vars = c("Catholic", "Protestant", "Non.religious", "Other")
  5. )

类似base系统,ggplot2默认使用竖直的条形图;添加coord_flip可使它翻转为水平的条形图。最后,因为我们已知数据集中的每个条形的长度(无需再作计算),所以必须把stat = "identity"传递到geom中。默认情况下,条形图都是可堆积的,如图14-46所示:

  1. ggplot(religions_long, aes(State, value, fill = variable)) +
  2. geom_bar(stat = "identity") +
  3. coord_flip()

图像说明文字

图14-46:使用ggplot2绘制的堆积条形图

如果不想使用堆积,我们必须把参数position = "dodge"传递给geom_bar。如图14-47所示:

  1. ggplot(religions_long, aes(State, value, fill = variable)) +
  2. geom_bar(stat = "identity", position = "dodge") +
  3. coord_flip()

图像说明文字

图14-47:使用ggplot2绘制并列(dodged)条形图

此参数的另一种选项是position = "fill",它所创建出的每个堆积条都具有同样的高度,范围是0~100% 。试试吧!