《R数据科学》学习笔记|Note3:使用ggplot2进行数据可视化(下)

点击蓝字

关注我!

写在前面

本系列为《R数据科学》(R for Data Science)的学习笔记。相较于其他R语言教程来说,本书一个很大的优势就是直接从实用的R包出发,来熟悉R及数据科学。更新过程中,读者朋友如发现错误,欢迎指正。如果有疑问,也可以在评论区留言或后台私信。希望各位读者朋友能学有所得!

BOOK

1.5

几何对象

以下两张图的相似程度有多大?

两张图有同样的 x 变量和 y 变量,而且描述的是同样的数据。但这两张图并不一样,它们各自使用不同的可视化对象来表示数据。在 ggplot2 语法中,我们称它们使用了不同的几何对象。

几何对象是图中用来表示数据的几何图形对象。我们经常根据图中使用的几何对象类型来描述相应的图。例如,条形图使用了条形几何对象,折线图使用了直线几何对象,箱线图使用了矩形和直线几何对象。散点图使用了点几何对象。如上面的两幅图所示。左侧的图使用了点几何对象,右侧的图使用了平滑曲线几何对象,以一条平滑曲线来拟合数据。 要想改变图中的几何对象,需要修改添加在 ggplot() 函数中的几何对象函数。举例来说,要想绘制出上图,你可以使用以下代码:

1# 左图
2ggplot(data = mpg) +
3 geom_point(mapping = aes(x = displ, y = hwy))
4# 右图
5ggplot(data = mpg) +
6 geom_smooth(mapping = aes(x = displ, y = hwy))

根据表示汽车驱动系统的 drv 变量的值,这里的geom_smooth() 函数分别用 3 条曲线来表示汽车。

1ggplot(data = mpg) +
2 geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))

只要将一个图形属性映射为一个离散变量(如上个示例中的 linetype),ggplot2 就会自动对数据进行分组来绘制多个几何对象。这个功能非常方便,因为按照图形属性的这种分组不用添加图例,也不用为几何对象添加区分特征:

1ggplot(data = mpg) +
2 geom_smooth(mapping = aes(x = displ, y = hwy))
3ggplot(data = mpg) +
4 geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))
5ggplot(data = mpg) +
6 geom_smooth(
7 mapping = aes(x = displ, y = hwy, color = drv),
8 show.legend = FALSE #不添加图例
9 )

要想在同一张图中显示多个几何对象,可以向 ggplot() 函数中添加多个几何对象函数:

1ggplot(data = mpg) +
2 geom_point(mapping = aes(x = displ, y = hwy)) +
3 geom_smooth(mapping = aes(x = displ, y = hwy))

但是,这样代码就产生了一些重复。假如你想将 y 轴上的变量从 hwy 改成 cty,那么就要在两个地方修改这个变量,但你或许会漏掉一处。避免这种重复的方法是将一组映射传递给 ggplot() 函数。ggplot2 会将这些映射作为全局映射应用到图中的每个几何对象中。换句话说,以下代码将绘制出与上面代码同样的图:

1ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
2 geom_point() +
3 geom_smooth()

如果将映射放在几何对象函数中,那么 ggplot2 会将其看作这个图层的局部映射,它将使用这些映射扩展或覆盖全局映射,但仅对该图层有效。这样一来,我们就可以在不同的图层中显示不同的图形属性:

1ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
2 geom_point(mapping = aes(color = class)) +
3 geom_smooth()

同理,你也可以为不同的图层指定不同的数据。下图中的平滑曲线表示的只是 mpg 数据集的一个子集,即微型车。geom_smooth() 函数中的局部数据参数覆盖了 ggplot() 函数中的全局数据参数,当然仅对这个图层有效:

1ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
2 geom_point(mapping = aes(color = class)) +
3 geom_smooth(
4 data = filter(mpg, class == "subcompact"),#filter()函数用来选取部分数据
5 se = FALSE #se 是否在平滑曲线周围显示置信区间,False不显示,True显示
6 )

1.6

统计变换

下面的条形图显示了 diamonds 数据集中按照 cut 变量分组的各种钻石的总数量。diamonds 数据集是 ggplot2的内置数据集,包含大约 54000 颗钻石的信息,每颗钻石具有 price、carat、color、 clarity cut 变量。条形图显示,高质量切割钻石的数量要比低质量切割钻石的数量多:

1ggplot(data = diamonds) +
2 geom_bar(mapping = aes(x = cut))

条形图 x 轴显示的是 cut,这是diamonds 数据集中的一个变量。y 轴显示的是 count,但count 不是 diamonds 中的变量!那么 count 来自哪里呢?很多图形绘制的是数据集的原始数据,比如散点图。另外一些图形则可以绘制那些计算出的新数据,比如条形图。

• 条形图、直方图和频率多边形图可以对数据进行分箱,然后绘制出分箱数量和落在每个分箱的数据点的数量。 

• 平滑曲线会为数据拟合一个模型,然后绘制出模型预测值。 

• 箱线图可以计算出数据分布的多种摘要统计量,并显示一个特殊形式的箱体。绘图时用来计算新数据的算法称为 stat(statistical transformation,统计变换)。下图描述了geom_bar() 函数的统计变换过程。

通常来说,几何对象函数和统计变换函数可以互换使用。例如,你可以使用 stat_count()替换 geom_bar() 来重新生成前面那张图:

1ggplot(data = diamonds) +
2 stat_count(mapping = aes(x = cut))

如果想显示一张表示比例(而不是计数)的条形图

1ggplot(data = diamonds) +
2 geom_bar(
3 mapping = aes(x = cut, y = ..prop.., group = 1)
4 )

你可能想要在代码中强调统计变换。例如,你可以使用 stat_summary() 函数将人们的注意力吸引到你计算出的那些摘要统计量上。stat_summary() 函数为 x 的每个唯一值计算 y 值的摘要统计:

1ggplot(data = diamonds) +
2 stat_summary(
3 mapping = aes(x = cut, y = depth),
4 fun.min = min,
5 fun.max = max,
6 fun = median #统计最大、最小值,中位数
7 )

ggplot2 提供了 20 多个统计变换以供你使用。每个统计变换都是一个函数,因此你可以按 照通用方式获得帮助,例如 ?stat_bin

1.7

位置调整

条形图还有一项神奇的功能,你可以使用 color 或者 fill 图形属性来为条 形图上色:

1ggplot(data = diamonds) +
2  geom_bar(mapping = aes(x = cut, color = cut)) #边框
3ggplot(data = diamonds) +
4  geom_bar(mapping = aes(x = cut, fill = cut)) #填充

注意,如果将 fill 图形属性映射到另一个变量(如 clarity),那么条形会自动分块堆叠起来。每个彩色矩形表示 cutclarity 的一种组合。

1ggplot(data = diamonds) +
2 geom_bar(mapping = aes(x = cut, fill = clarity))

这种堆叠是由 position 参数设定的位置调整功能自动完成的。如果不想生成堆叠式条形图,你还可以使用以下 3 种选项之一:"identity"、"fill" "dodge"。

• position = "identity" 将每个对象直接显示在图中。这种方式不太适合条形图,因为条形会彼此重叠。为了让重叠部分能够显示出来,我们可以设置 alpha 参数为一个较小的数,从而使得条形略微透明;或者设定 fill = NA,让条形完全透明:

 1ggplot(
 2 data = diamonds,
 3 mapping = aes(x = cut, fill = clarity)
 4) +
 5 geom_bar(alpha = 1/5, position = "identity")#透明度,上图
 6ggplot(
 7 data = diamonds,
 8 mapping = aes(x = cut, color = clarity)
 9) +
10 geom_bar(fill = NA, position = "identity") #空白填充,下图

position = "fill" 的效果与堆叠相似,但每组堆叠条形具有同样的高度,因此这种条形图可以非常轻松地比较各组间的比例:

1ggplot(data = diamonds) +
2  geom_bar(
3    mapping = aes(x = cut, fill = clarity),
4    position = "fill"
5  )


position = "dodge" 将每组中的条形依次并列放置,这样可以非常轻松地比较每个条形表示的具体数值:

1ggplot(data = diamonds) +
2  geom_bar(
3    mapping = aes(x = cut, fill = clarity),
4    position = "dodge"
5  )

通过将位置调整方式设为“抖动”,可以避免网格化排列。position = "jitter" 为每个数据点添加一个很小的随机扰动,这样就可以将重叠的点分散开来,因为不可能有两个点会收到同样的随机扰动:

1ggplot(data = mpg) +
2 geom_point(
3 mapping = aes(x = displ, y = hwy),
4 position = "jitter"
5 )

添加随机性来改善图形似乎是一种奇怪的方式,然而尽管这种方式会损失图形的精确性, 但可以大大提高图形的启发性。因为这种操作的用处非常大,所以 ggplot2 提供了geom_ point(position = "jitter") 的一种快速实现方式:geom_jitter()

1ggplot(data = mpg) +
2  geom_jitter(
3    mapping = aes(x = displ, y = hwy))

1.8

坐标系

坐标系可能是 ggplot2 中最复杂的部分。默认的坐标系是笛卡儿直角坐标系,可以通过其 独立作用的 x 坐标和 y 坐标找到每个数据点。偶尔也会用到一些其他类型的坐标系。

coord_flip() 函数可以交换 x 轴和 y 轴。当想要绘制水平箱线图时,这非常有用。它也非常适合使用长标签,但要想在 x 轴上不重叠地安排好它们是非常困难的:

1ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
2  geom_boxplot() #左图
3ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
4  geom_boxplot() +
5  coord_flip() #右图

coord_quickmap() 函数可以为地图设置合适的纵横比。当使用 ggplot2 绘制空间数据时, 这个函数特别重要:

1BiocManager::install('maps')
2install.packages("maps") #下载maps包(两种方法任选一种可用的)
3library(maps) #加载maps
4nz <- map_data("nz") #导入内置数据
5ggplot(nz, aes(long, lat, group = group)) +
6  geom_polygon(fill = "white", color = "black") #左图 
7ggplot(nz, aes(long, lat, group = group)) +
8  geom_polygon(fill = "white", color = "black") +
9  coord_quickmap() #调整纵横比,右图

coord_polar() 函数使用极坐标系。极坐标系可以揭示出条形图和鸡冠花图间的一种有 趣联系:

 1bar <- ggplot(data = diamonds) +
 2  geom_bar(
 3    mapping = aes(x = cut, fill = cut),
 4    show.legend = FALSE,
 5    width = 1
 6  ) +
 7  theme(aspect.ratio = 1) +
 8  labs(x = NULL, y = NULL)
 9bar
10bar + coord_flip()
11bar + coord_polar()

1.9

图形分层语法

在前面几节中,你学到的绝不仅仅是如何绘制散点图、条形图和箱线图,而是使用 ggplot2绘制任何类型图形的基础知识。为了说明这一点,我们向前面的代码模板中添加位置调整、统计变换、坐标系和分面:

1ggplot(data = <DATA>) +
2 <GEOM_FUNCTION>(
3 mapping = aes(<MAPPINGS>),
4 stat = <STAT>,
5 position = <POSITION>
6 ) +
7 <COORDINATE_FUNCTION> +
8 <FACET_FUNCTION>

模板中的 7 个参数一同组成了图形语法,即用于建立图形的一个正式语法系统。你可以将任何图形精确地描述为数据集、几何对象、映射集合、统计变换、位置调整、坐标系和分面模式的一个组合,图形语法正是基于这样的深刻理解构建出来的。

为了说明图形语法的工作方式,我们看一下如何从头开始构建一个基本图形:首先需要有 一个数据集,然后(通过统计变换)将其转换为想要显示的信息。

接下来,你可以选择一个几何对象来表示转换后的数据中的每个观测值,然后选择几何对象的图形属性来表示数据中的变量,这会将每个变量的值映射为图形属性的水平。

下一步是选择放置几何对象的坐标系。你可以使用对象位置(对象本身的一个图形属性) 来显示 x 变量和 y 变量的值。这样就生成了一张完整的图。但你还可以进一步调整几何对象在坐标系中的位置(位置调整),或者将图划分为多个子图(分面)。你还可以通过添加一个或多个附加图层对图进行扩展,其中每个附加图层都使用一个数据集、一个几何对象、一个映射集合、一个统计变换和一个位置调整。

你可以使用这种方法构建你能够想象到的任何图形。换句话说,你可以使用在本章中学到 的代码模板来构建成千上万种独特的图形。

— END —

往期 · 推荐

《R数据科学》学习笔记|Note1:绪论

《R数据科学》学习笔记|Note2:使用ggplot2进行数据可视化(上)

零基础"机器学习"自学笔记|Note5:多变量线性回归

零基础"机器学习"自学笔记|Note6:正规方程及其推导(内附详细推导过程)

零基础"机器学习"自学笔记|Note6:正规方程及其推导(内附详细推导过程)

欢迎关注 木舟笔记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值