这里是佳奥!初步掌握有关数据的管理以后,我们将进一步学习有关基本图形的绘制。
本章,我们将关注那些可以帮助理解单个类别型或连续型变量的图形。主题包括:1、将变量的分布作可视化展示。2、通过结果变量进行跨组比较。
在接下来的几节中,我们将探索条形图、饼图、扇形图、直方图、核密度图、箱线图、小提琴图和点图的用法。
让我们开始吧!
1 条形图
条形图通过垂直或水平展示类别型变量的分布(也就是频数)。下面函数最简单的用法:
其中height是一个向量或矩阵。
接下来的学习我们需要安装vcd包以及随vcd包分发的Arthritis数据框中的数据。
1.1 简单的条形图
若height是一个向量,则它的值就确定了各条形的高度,并将绘制一幅垂直的条形图。
使用选项 horiz = TRUE 则会生成一幅水平条形图。
当然,我们也可以添加标注选项。选项main可添加一个图形标题,而选项xlab和ylab则会分别添加x轴和y轴标签。
在关节炎研究中,变量Improved记录了对每位接受了安慰剂或药物治疗的病人的治疗结果:
这里我们看到,28位病人有了明显改善,14人有部分改善,而42人没有改善。
我们将在第7篇更充分地讨论使用table( )函数提取各单元的计数的方法。
于是我们可以使用一幅垂直或水平的条形图来绘制变量counts。
小提示
若要绘制的类别型变量是一个因子或有序型因子,就可以使用函数plot( )快速创建一幅垂直条形图。
由于Arthritis$Improved是一个因子,所以代码:
将和上述代码生成相同的条形图,而无需使用table( )函数将其表格化。
1.2 堆砌条形图和分组条形图
如果height是一个矩阵而不是一个向量,则绘图结果将是一幅堆砌条形图或分组条形图。
若beside=FALSE(默认值),则矩阵中的每一列都将生成图中的一个条形,各列中的值将给出堆砌的“子条”的高度。
若beside=TRUE,则矩阵中的每一列都表示一个分组,各列中的值将并列而不是堆砌。
考虑治疗类型和改善情况的列联表:
第一个barplot函数绘制了一幅堆砌条形图,而第二个绘制了一幅分组条形图。
我们同时使用col选项为绘制的条形添加了颜色。
参数legend.text为图例提供了各条形的标签(仅在height为一个矩阵时有用)。
1.3 均值条形图
条形图并不一定要基于计数数据或频率数据。
我们可以使用数据整合函数并将结果传递给barplot( )函数,来创建表示均值、中位数、标准差等的条形图。
美国各地区平均文盲率排序的条形图:
上述代码将均值从小到大排序。
使用title( )函数与调用plot( )时添加main选项是等价的。
means$x是包含各条形高度的向量,而添加选项names.arg=means$Group.1是为了展示标签。
我们可以进一步完善这个示例。各个条形可以使用lines( )函数绘制的线段连接起来。你也可以使用ggplots包中的barplot2( )函数创建叠加有置信区间的均值条形图。(挖一个坑,下一步学这个包)
1.4 条形图微调
有若干种方式可以微调条形图的外观。
例如,随着条数的增多,条形的标签可能会开始重叠。我们可以使用参数cex.names来减小字号。将其指定为小于1的值可以缩小标签的大小。
可选的参数names.arg允许我们指定一个字符向量作为条形的标签名。
同样可以使用图形参数辅助调整文本间隔。下列代码给出了一个示例:
本例中,我们(使用las=2)旋转了条形的标签、修改了标签文本,并(使用mar)增加了y边界的大小,为了让标签更合适,(使用cex.names=0.8)缩小了字体大小。
par( )函数能够让你对R的默认图形做出大量修改,具体参见第3篇。
1.5 棘状图
让我们再来看一种特殊的条形图,它称为棘状图(spinogram)。
棘状图对堆砌条形图进行了重缩放,这样每个条形的高度均为1,每一段的高度即表示比例。
棘状图可由vcd包中的函数spine( )绘制。以下代码可以生成一幅简单的棘状图:
关节炎治疗结果的棘状图
输出如图所示:治疗组同安慰剂组相比,获得显著改善的患者比例明显更高。
2 饼图
因为相对于面积,人们对长度的判断更精确。也许由于这个原因,R中饼图的选项与其他统计软件相比十分有限。
饼图可由以下函数创建:
其中x是一个非负数值向量,表示每个扇形的面积,而labels则是表示各扇形标签的字符型向量。
首先,我们做了图形设置,这样四幅图形就会被组合为一幅。(多幅图形的组合在第3篇中介绍过。)
然后,我们输入了前三幅图形将会使用的数据。
对于第二幅饼图,将样本数转换为比例值,并将这项信息添加到了各扇形的标签上。如第3篇所述, 第二幅饼图使用rainbow( ) 函数定义了各扇形的颜色。这里的rainbow(length(lbls2))将被解析为rainbow(5),即为图形提供了五种颜色。
第三幅是使用plotrix包中的pie3D()函数创建的三维饼图。
第四幅图演示了如何从表格创建饼图。在本例中计算了美国不同地区的州数,并在绘制图形之前将此信息附加到了标签上。
饼图让比较各扇形的值变得困难(除非这些值被附加在标签上)。为改善这种状况,我们创造了一种称为扇形图(fan plot)的饼图变种。扇形图为用户提供了一种同时展示相对数量和相互差异的方法。
在R中,扇形图是通过plotrix包中的fan.plot( )函数实现的。
在一幅扇形图中,各个扇形相互叠加,并对半径做了修改,这样所有扇形就都是可见的。
在这里可见德国对应的扇形是最大的,而美国的扇形大小约为其60%。法国的扇形大小似乎是德国的一半,是澳大利亚的两倍。
请记住,在这里扇形的宽度(width)是重要的,而半径并不重要。
3 直方图
直方图通过在X 轴上将值域分割为一定数量的组,在Y 轴上显示相应值的频数,展示了连续型变量的分布。
可以使用如下函数创建直方图:
其中的x是一个由数据值组成的数值向量。
参数freq=FALSE 表示根据概率密度而不是频数绘制图形。
参数breaks用于控制组的数量。在定义直方图中的单元时,默认将生成等距切分。
下列代码提供了绘制四种直方图的代码:
第一幅直方图展示了未指定任何选项时的默认图形。这个例子共创建了五个组,并且显示了默认的标题和坐标轴标签。
对于第二幅直方图,我们将组数指定为12,使用红色填充条形,并添加了标签和标题。
第三幅直方图保留了上一幅图中的颜色、组数、标签和标题设置,又叠加了一条密度曲线和轴须图(rug plot)。
这条密度曲线是一个核密度估计,它为数据的分布提供了一种更加平滑的描述。我们使用lines( )函数叠加了这条蓝色、双倍默认线条宽度的曲线。
轴须图是实际数据值的一种一维呈现方式。如果数据中有许多相同的值,可以使用如下代码将轴须图的数据打散:
这样将向每个数据点添加一个小的随机值(一个±amount之间的均匀分布随机数),以避免重叠的点产生影响。
第四幅直方图与第二幅类似,只是拥有一条叠加在上面的正态曲线和一个将图形围绕起来的盒型。用于叠加正态曲线的代码来源于R-help邮件列表上由Peter Dalgaard发表的建议。盒型是使用box()函数生成的。
4 核密度图
核密度估计是用于估计随机变量概率密度函数的一种非参数方法。从总体上讲,核密度图为一种用来观察连续型变量分布的有效方法。
绘制密度图的方法(不叠加到另一幅图上方)为:
其中的x是一个数值型向量。
由于plot( )函数会创建一幅新的图形,所以要向一幅已经存在的图形上叠加一条密度曲线,可以使用lines( )函数。
下面代码给出了两幅核密度图示例:
在第一幅图中,我们看到的是完全使用默认设置创建的最简图形。
在第二幅图中,添加了一个标题,将曲线修改为蓝色,使用实心红色填充了曲线下方的区域,并添加了棕色的轴须图(轴密度)。
polygon( )函数根据顶点的x和y坐标(本例中由density()函数提供)绘制了多边形。
核密度图可用于比较组间差异。使用sm包中的sm.density.compare( )函数可向图形叠加两组或更多的核密度图。
使用格式为:
其中的x是一个数值型向量,factor是一个分组变量。
下列代码比较了拥有4个、6个或8个汽缸车型的每加仑汽油行驶英里数:
首先,par( )函数将所绘制的线条设置为双倍宽度(lwd=2)。
接下来,载入了sm包,并绑定了数据框mtcars。在数据框mtcars 中,变量cyl是一个以4、6或8编码的数值型变量。
为了向图形提供值的标签,这里cyl转换为名为cyl.f的因子。
其次,函数sm.density.compare()创建了图形 ,一条title( )语句添加了主标题。
最后,添加了一个图例以增加可解释性 :
首先创建的是一个颜色向量,这里的colfill值为c(2, 3, 4)。
然后通过legend()函数向图形上添加一个图例。
第一个参数值locator(1)表示用鼠标点击想让图例出现的位置来交互式地放置这个图例。
第二个参数值则是由标签组成的字符向量。
第三个参数值使用向量colfill为cyl.f的每一个水平指定了一种颜色。
如下图所见,核密度图的叠加不失为一种在某个结果变量上跨组比较观测的强大方法。我们可以看到不同组所含值的分布形状,以及不同组之间的重叠程度。
5 箱线图
箱线图(又称盒须图)通过绘制连续型变量的五数总括,即最小值、下四分位数(第25百分位数)、中位数(第50百分位数)、上四分位数(第75百分位数)以及最大值,描述了连续型变量的分布。
箱线图能够显示出可能为离群点(范围±1.5*IQR以外的值,IQR表示四分位距,即上四分位数与下四分位数的差值)的观测。
例如:
生成了如图所示的图形。为了图解各个组成部分,补充了一张增加标注的图。
默认情况下,两条须的延伸极限不会超过盒型各端加1.5倍四分位距的范围。此范围以外的值将以点来表示(在这里没有画出)。
举例来说,在我们的车型样本中,每加仑汽油行驶英里数的中位数是19.2,50%的值都落在了15.3和22.8之间,最小值为10.4,最大值为33.9。
那么如何从图中如此精确地读出了这些值呢?
执行boxplot.stats(mtcars$mpg)即可输出用于构建图形的统计量:
图中似乎不存在离群点,而且略微正偏(上侧的须较下侧的须更长)。
5.1 使用并列箱线图进行跨组比较
箱线图可以展示单个变量或分组变量。使用格式为:
其中的formula是一个公式,dataframe代表提供数据的数据框(或列表)。
一个示例公式为y ~A,这将为类别型变量A的每个值并列地生成数值型变量y的箱线图。
公式y ~ A*B则将为类别型变量A和B所有水平的两两组合生成数值型变量y的箱线图。
添加参数varwidth=TRUE 将使箱线图的宽度与其样本大小的平方根成正比。
参数horizontal=TRUE可以反转坐标轴的方向。
在以下代码中,我们使用并列箱线图重新研究了四缸、六缸、八缸发动机对每加仑汽油行驶的英里数的影响:
在图中可以看到不同组间油耗的区别非常明显。
同时也可以发现,六缸车型的每加仑汽油行驶的英里数分布较其他两类车型更为均匀。
与六缸和八缸车型相比,四缸车型的每加仑汽油行驶的英里数散布最广(且正偏)。
在八缸组还有一个离群点。
箱线图灵活多变,通过添加notch=TRUE,可以得到含凹槽的箱线图。
若两个箱的凹槽互不重叠,则表明它们的中位数有显著差异。
以下代码将为我们的车型油耗示例创建一幅含凹槽的箱线图:
参数col以红色填充了箱线图,而varwidth=TRUE则使箱线图的宽度与它们各自的样本大小成正比。
在图中可以看到,四缸、六缸、八缸车型的油耗中位数是不同的。
随着汽缸数的减少,油耗明显降低。
最后,我们还可以以为多个分组因子绘制箱线图。
下列代码为不同缸数和不同变速箱类型的车型绘制了每加仑汽油行驶英里数的箱线图。
同样地,这里使用参数col为箱线图进行了着色。
请注意颜色的循环使用。在本例中,共有六幅箱线图和两种指定的颜色,所以颜色将重复使用三次。
两个交叉因子的箱线图:
下图再一次清晰地显示出油耗随着缸数的下降而减少。
对于四缸和六缸车型,标准变速箱(standard)的油耗更高。
但是对于八缸车型,油耗似乎没有差别。
我们也可以从箱线图的宽度看出,四缸标准变速箱的车型和八缸自动变速箱的车型在数据集中最常见。
5.2 小提琴图
接下来研究一种称为小提琴图(violin plot)的箱线图变种。
小提琴图是箱线图与核密度图的结合。
我们可以使用vioplot包中的vioplot( )函数绘制它。
vioplot( )函数的使用格式为:
其中x1, x2, …表示要绘制的一个或多个数值向量(将为每个向量绘制一幅小提琴图)。
参数names是小提琴图中标签的字符向量,而col是一个为每幅小提琴图指定颜色的向量。
注意
vioplot( )函数要求将要绘制的不同组分离到不同的变量中。
小提琴图基本上是核密度图以镜像方式在箱线图上的叠加。
在图中,白点是中位数,黑色盒型的范围是下四分位点到上四分位点,细黑线表示须。外部形状即为核密度估计。
6 点图
点图提供了一种在简单水平刻度上绘制大量有标签值的方法。
可以使用dotchart( )函数创建点图,格式为:
其中的x是一个数值向量,而labels则是由每个点的标签组成的向量。
可以通过添加参数groups来选定一个因子,用以指定x中元素的分组方式。
如果这样做,则参数gcolor可以控制不同组标签的颜色,cex可控制标签的大小。
这里是mtcars数据集的一个示例:
绘图结果:
上图可以在同一个水平轴上观察每种车型的每加仑汽油行驶英里数。
通常来说,点图在经过排序并且分组变量被不同的符号和颜色区分开的时候最有用。
分组、排序、着色后的点图:
在本例中,根据每加仑汽油行驶英里数(从最低到最高)对数据框mtcars进行排序,结果保存为数据框x。
数值向量cyl被转换为一个因子。
一个字符型向量(color)被添加到了数据框x中,根据cyl的值,它所含的值为"red"、"blue"或"darkgreen"。
另外,各数据点的标签取自数据框的行名(车辆型号)。大小为标准0.7倍。数据点根据汽缸数量分组。数字4、6和8以黑色显示。点和标签的颜色来自向量color,点以填充的圆圈表示。
在图中,许多特征第一次明显起来。
我们再次看到,随着汽缸数的减少,每加仑汽油行驶的英里数有了增加。
但同时也看到了例外。例如,Pontiac Firebird有8个汽缸,但较六缸的Mercury280C和Valiant的行驶英里数更多。六缸的Hornet 4 Drive与四缸的Volvo 142E的每加仑汽油行驶英里数相同。
同样明显的是,Toyota Corolla的油耗最低,而Lincoln Continental和Cadillac Fleetwood是英里数较低一端的离群点。
在本例中,我们可以从点图中获得显著的洞察力,因为每个点都有标签,每个点的值都有其内在含义,并且这些点是以一种能够促进比较的方式排布的。
但是随着数据点的增多,点图的实用性随之下降。
注意
点图有许多变种。Jacoby(2006)对点图进行了非常有意义的讨论,并且提供了创新型应用的R代码。此外,Hmisc包也提供了一个带有许多附加功能的点图函数(dotchart2)。
7 小结
本章我们学习了描述连续型和类别型变量的方法。我们看到了如何用条形图和饼图(在较小程度上)了解类别型变量的分布, 以及如何通过堆砌条形图和分组条形图理解不同类别型输出的组间差异。
我们同时探索了直方图、核密度图、箱线图、轴须图以及点图可视化连续型变量分布的方式。
最后,我们探索了使用叠加的核密度图、并列箱线图和分组点图可视化连续型输出变量组间差异的方法。
下一篇,我们将关注用于描述分布和二元关系的定量统计方法以及一类推断方法,这类推断方法可用于评估变量间的关系是真实存在的,还是由于抽样误差导致的。
那么我们下一篇再见!