第一章使用ggplot2进行数据可视化
library(tidyverse)
查看运行环境
devtools::session_info(c("tidyverse"))
- Session info ---------------------------------------------------------------
setting value
version R version 3.6.1 (2019-07-05)
os Windows 10 x64
system x86_64, mingw32
ui RTerm
language (EN)
collate Chinese (Simplified)_China.936
ctype Chinese (Simplified)_China.936
tz Asia/Taipei
date 2020-05-26
- Packages -------------------------------------------------------------------
package * version date lib source
askpass 1.1 2019-01-13 [1] CRAN (R 3.6.1)
assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.1)
backports 1.1.5 2019-10-02 [1] CRAN (R 3.6.1)
base64enc 0.1-3 2015-07-28 [1] CRAN (R 3.6.0)
BH 1.72.0-3 2020-01-08 [1] CRAN (R 3.6.2)
broom 0.5.4 2020-01-27 [1] CRAN (R 3.6.2)
callr 3.4.1 2020-01-24 [2] CRAN (R 3.6.2)
cellranger 1.1.0 2016-07-27 [1] CRAN (R 3.6.2)
cli 2.0.1 2020-01-08 [1] CRAN (R 3.6.2)
clipr 0.7.0 2019-07-23 [2] CRAN (R 3.6.1)
colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.1)
crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.1)
curl 4.3 2019-12-02 [1] CRAN (R 3.6.2)
DBI 1.1.0 2019-12-15 [2] CRAN (R 3.6.2)
dbplyr 1.4.2 2019-06-17 [1] CRAN (R 3.6.2)
digest 0.6.23 2019-11-23 [1] CRAN (R 3.6.2)
dplyr * 0.8.3 2019-07-04 [1] CRAN (R 3.6.1)
ellipsis 0.3.0 2019-09-20 [1] CRAN (R 3.6.1)
evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.3)
fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.2)
farver 2.0.3 2020-01-16 [1] CRAN (R 3.6.2)
forcats * 0.4.0 2019-02-17 [1] CRAN (R 3.6.2)
fs 1.3.1 2019-05-06 [2] CRAN (R 3.6.1)
generics 0.0.2 2018-11-29 [2] CRAN (R 3.6.1)
ggplot2 * 3.2.1 2019-08-10 [1] CRAN (R 3.6.1)
glue 1.3.1 2019-03-12 [1] CRAN (R 3.6.1)
gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.1)
haven 2.2.0 2019-11-08 [1] CRAN (R 3.6.2)
highr 0.8 2019-03-20 [1] CRAN (R 3.6.3)
hms 0.5.3 2020-01-08 [1] CRAN (R 3.6.2)
htmltools 0.4.0 2019-10-04 [1] CRAN (R 3.6.1)
httr 1.4.1 2019-08-05 [1] CRAN (R 3.6.1)
jsonlite 1.6 2018-12-07 [1] CRAN (R 3.6.1)
knitr 1.28 2020-02-06 [1] CRAN (R 3.6.3)
labeling 0.3 2014-08-23 [1] CRAN (R 3.6.0)
lattice 0.20-38 2018-11-04 [2] CRAN (R 3.6.1)
lazyeval 0.2.2 2019-03-15 [1] CRAN (R 3.6.1)
lifecycle 0.1.0 2019-08-01 [1] CRAN (R 3.6.1)
lubridate 1.7.4 2018-04-11 [1] CRAN (R 3.6.2)
magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.1)
markdown 1.1 2019-08-07 [1] CRAN (R 3.6.3)
MASS 7.3-51.4 2019-03-31 [2] CRAN (R 3.6.1)
Matrix 1.2-17 2019-03-22 [2] CRAN (R 3.6.1)
mgcv 1.8-31 2019-11-09 [2] CRAN (R 3.6.2)
mime 0.8 2019-12-19 [1] CRAN (R 3.6.2)
modelr 0.1.5 2019-08-08 [1] CRAN (R 3.6.2)
munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.1)
nlme 3.1-140 2019-05-12 [2] CRAN (R 3.6.1)
openssl 1.4.1 2019-07-18 [1] CRAN (R 3.6.1)
pillar 1.4.3 2019-12-20 [1] CRAN (R 3.6.2)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.1)
plogr 0.2.0 2018-03-25 [1] CRAN (R 3.6.1)
plyr 1.8.5 2019-12-10 [1] CRAN (R 3.6.2)
prettyunits 1.1.1 2020-01-24 [2] CRAN (R 3.6.2)
processx 3.4.1 2019-07-18 [2] CRAN (R 3.6.1)
progress 1.2.2 2019-05-16 [2] CRAN (R 3.6.1)
ps 1.3.0 2018-12-21 [2] CRAN (R 3.6.1)
purrr * 0.3.3 2019-10-18 [1] CRAN (R 3.6.2)
R6 2.4.1 2019-11-12 [1] CRAN (R 3.6.2)
RColorBrewer 1.1-2 2014-12-07 [1] CRAN (R 3.6.0)
Rcpp 1.0.2 2019-07-25 [1] CRAN (R 3.6.1)
readr * 1.3.1 2018-12-21 [1] CRAN (R 3.6.2)
readxl 1.3.1 2019-03-13 [1] CRAN (R 3.6.2)
rematch 1.0.1 2016-04-21 [1] CRAN (R 3.6.2)
reprex 0.3.0 2019-05-16 [1] CRAN (R 3.6.2)
reshape2 1.4.3 2017-12-11 [1] CRAN (R 3.6.1)
rlang 0.4.5 2020-03-01 [1] CRAN (R 3.6.3)
rmarkdown 2.1 2020-01-20 [1] CRAN (R 3.6.1)
rstudioapi 0.11 2020-02-07 [1] CRAN (R 3.6.3)
rvest 0.3.5 2019-11-08 [1] CRAN (R 3.6.2)
scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.2)
selectr 0.4-2 2019-11-20 [1] CRAN (R 3.6.2)
stringi 1.4.3 2019-03-12 [1] CRAN (R 3.6.0)
stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.6.1)
sys 3.3 2019-08-21 [1] CRAN (R 3.6.1)
tibble * 2.1.3 2019-06-06 [1] CRAN (R 3.6.1)
tidyr * 1.0.0 2019-09-11 [1] CRAN (R 3.6.1)
tidyselect 1.0.0 2020-01-27 [1] CRAN (R 3.6.3)
tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 3.6.2)
tinytex 0.19 2020-01-14 [1] CRAN (R 3.6.2)
utf8 1.1.4 2018-05-24 [1] CRAN (R 3.6.1)
vctrs 0.2.99.9002 2020-01-13 [1] Github (r-lib/vctrs@038b6af)
viridisLite 0.3.0 2018-02-01 [1] CRAN (R 3.6.1)
whisker 0.4 2019-08-28 [2] CRAN (R 3.6.1)
withr 2.1.2 2018-03-15 [1] CRAN (R 3.6.1)
xfun 0.12 2020-01-13 [1] CRAN (R 3.6.3)
xml2 1.2.2 2019-08-09 [2] CRAN (R 3.6.1)
yaml 2.2.0 2018-07-25 [1] CRAN (R 3.6.0)
[1] C:/Users/wlx/Documents/R/win-library/3.6
[2] C:/Program Files/R/R-3.6.1/library
ggplot2::mpg libray之后就不用这样了
1.mpg数据框
数据框是变量(列)和观测(行)的矩形集合。mpg是ggplot2的内置数据框。
拿到一个数据首先就要观察它!忘了谁说的反正好有道理。
Fuel economy data from 1999 and 2008 for 38 popular models of car
234 行x 11列
1.manufacturer:生产商 15个
2.model:型号 38个
3.displ:引擎排量-L 35个,单位为升,小数
4.year:出厂年份
5.cly:汽缸数 4,5,6,8
6.trans:变速方式:10个
7.dry:驱动方式 f r 4
8.cty :每加仑汽油能跑的公里数(城市)21个,整数
9.hwy:燃油效率:每加仑汽油能跑的公里数(高速路)单位英里/加仑,燃油效率高说明省油。 27个,整数。
10.fl:燃油类型,五个 p r e d c
11.class:车型 七个 compact midsize suv 2seater minivan pickup subcompact
library(ggplot2) ggplot包含在tidyverse中,不用再单独library
mpg
# A tibble: 234 x 11
manufacturer model displ year cyl trans drv cty hwy fl class
<chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
1 audi a4 1.8 1999 4 auto(l~ f 18 29 p comp~
2 audi a4 1.8 1999 4 manual~ f 21 29 p comp~
3 audi a4 2 2008 4 manual~ f 20 31 p comp~
4 audi a4 2 2008 4 auto(a~ f 21 30 p comp~
5 audi a4 2.8 1999 6 auto(l~ f 16 26 p comp~
6 audi a4 2.8 1999 6 manual~ f 18 26 p comp~
7 audi a4 3.1 2008 6 auto(a~ f 18 27 p comp~
8 audi a4 quat~ 1.8 1999 4 manual~ 4 18 26 p comp~
9 audi a4 quat~ 1.8 1999 4 auto(l~ 4 16 25 p comp~
10 audi a4 quat~ 2 2008 4 manual~ 4 20 28 p comp~
# ... with 224 more rows
?mpg #查看帮助文档
用dplyr包的distinct函数
p<-mpg
library(dplyr)
distinct(p,manufacturer) #manufacturer替换为其他列名。仅显示非重复值,不显示重复次数。
# A tibble: 15 x 1
manufacturer
<chr>
1 audi
2 chevrolet
3 dodge
4 ford
5 honda
6 hyundai
7 jeep
8 land rover
9 lincoln
10 mercury
11 nissan
12 pontiac
13 subaru
14 toyota
15 volkswagen
count(p,manufacturer) #显示出现次数
# A tibble: 15 x 2
manufacturer n
<chr> <int>
1 audi 18
2 chevrolet 19
3 dodge 37
4 ford 25
5 honda 9
6 hyundai 14
7 jeep 8
8 land rover 4
9 lincoln 3
10 mercury 4
11 nissan 13
12 pontiac 5
13 subaru 14
14 toyota 34
15 volkswagen 27
count(p,class) #显示出现次数
# A tibble: 7 x 2
class n
<chr> <int>
1 2seater 5
2 compact 47
3 midsize 41
4 minivan 11
5 pickup 33
6 subcompact 35
7 suv 62
count(p,drv)
# A tibble: 3 x 2
drv n
<chr> <int>
1 4 103
2 f 106
3 r 25
count(p,cyl)
# A tibble: 4 x 2
cyl n
<int> <int>
1 4 81
2 5 4
3 6 79
4 8 70
基础作图
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
加颜色
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))
大小
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))
透明度和形状
将车型class映射给透明度
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, alpha = class))
将车型class映射给形状
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, shape = class))
(4)手动设置图形属性
例:所有点设为蓝色
(注意:color="blue"在aes()外)
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
(5)stroke-轮廓(笔者补充)
适用于散点图,21-24号形状
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, stroke = 3),shape=21)
5.分面
(1)依据单个变量分面 facet_wrap() #分子图
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class, nrow = 2) #分两行展示
nrow指定分面后显示几行
ncol指定分面后显示几列
注意~分面依据必须是离散型变量。
(2)依据两个变量分面 facet_grid()
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ cyl)
不需要指定nrow和ncol。
(3)不想在行或列维度中分面,用.代替变量名
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(. ~ cyl)
6.几何对象
也就是图的不同类型,如点图、折线图、直方图等。
(1)理解分组
将一个图形属性映射为一个离散型变量,ggplot2就会自动对数据进行分组来绘制多个几何对象。这种形式是隐式分组,不需要添加图例和区分特征。
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
将线性映射为drv(驱动方式,d,f,4)就会自动变成三条线型不同的线。
将颜色映射为drv,就会自动变成三条颜色不用的线。
分组
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))
隐式分组-线型
ggplot(data = mpg) +
geom_smooth(
mapping = aes(x = displ, y = hwy, linetype = drv),
)
隐式分组-颜色
ggplot(data = mpg) +
geom_smooth(
mapping = aes(x = displ, y = hwy, color = drv),
show.legend = FALSE #不显示图例
)
(2)同一张图显示多个几何对象--局部映射和全局映射
--这里涉及到图层啦。
局部映射-映射只对改图层有效
有多个几何对象时,映射语句要重复多次,又丑又麻烦。
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
geom_smooth(mapping = aes(x = displ, y = hwy))
全局映射--对所有图层生效
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() +
geom_smooth()
局部映射与全局映射冲突时,服从局部映射。
例如:
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth(data = filter(mpg, class == "subcompact"), se = FALSE)
如果出现报错,请library(dplyr) 或library(tidyverse)
Error in class == "subcompact" : comparison (1) is possible only for atomic and list types
这个报错是因为filter函数出自dplyr包,不加载就不能用~
ps:关于se=FALSE
se是standard error的缩写,se参数为拟合曲线添加标准误差带,也就是那个灰不啦叽的灰色背景带,默认是TRUE。
7.统计变换
(1)关于diamonds数据集 (笔者补充)
ggplot2内置数据集,包含53940颗钻石的信息。
carat:克拉
cut:切割质量
color:颜色等级
clarity:纯净度等级
depth:深度比例
table:钻石顶部相对于最宽点的宽度
price:价格
"x" "y" "z" :长宽深
↑以上来自帮助文档?diamonds
(2)统计变换函数和几何对象函数
统计变换:绘图时用来计算新数据的算法叫做统计变换stat
geom_bar做出的图纵坐标为count,是计算的新数据。
geom_bar的默认统计变换是stat_count,stat_count会计算出两个新变量-count(计数)和prop(proportions,比例)。
每个几何对象函数都有一个默认的统计变换,每个统计变换函数都又一个默认的几何对象。
用几何对象函数geom_bar作直方图,默认统计变换是stat_count,
diamonds
# A tibble: 53,940 x 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
# ... with 53,930 more rows
count(diamonds,cut) #显示出现次数
# A tibble: 5 x 2
cut n
<ord> <int>
1 Fair 1610
2 Good 4906
3 Very Good 12082
4 Premium 13791
5 Ideal 21551
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
用统计变换函数stat_count做计数统计图,默认几何对象是直方图。
ggplot(data [图片上传中...(image.png-18999c-1590543012090-0)]
= diamonds) +
stat_count(mapping = aes(x = cut))
这两个代码做出的图片结果是一致的。两种方法没有优劣之分。
(3)显示使用某种统计变换的原因
覆盖默认的统计变换
直方图默认的统计变换是stat_count,也就是统计计数。当需要直接用原表格的数据作图时就会需要覆盖默认的。
demo <- tribble(
~cut, ~freq,
"Fair", 1610,
"Good", 4906,
"Very Good", 12082,
"Premium", 13791,
"Ideal", 21551
) #新建表格并赋值给demo
ggplot(data = demo) +
geom_bar(mapping = aes(x = cut, y = freq), stat = "identity") #覆盖默认的统计变换,使用identity。
覆盖从统计变换生成变量到图形属性的默认映射
直方图默认的y轴是x轴的计数。此例子中x轴是是五种cut(切割质量),直方图自动统计了这五种质量的钻石的统计计数,当你不想使用计数,而是想显示各质量等级所占比例的时候就需要用到prop。
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, y = ..prop.., group = 1))
这里group=1的意思是把所有钻石作为一个整体,显示五种质量的钻石所占比例体现出来。如果不加这一句,就是每种质量的钻石各为一组来计算,那么比例就都是100%,显示五根大黑柱子,实在是丑出新高度。
在代码中强调统计变换
以stat_summary为例。
ggplot(data = diamonds) +
stat_summary(
mapping = aes(x = cut, y = depth),
fun.ymin = min,
fun.ymax = max,
fun.y = median
)
(小洁碎碎念:stat_summary的默认几何图形是geom_pointrange,而这个geom_pointrange默认的统计变换却是identity,如果你不知道其中猫腻,就会发现他俩代码竟然不可逆。。。一夫多妻的节奏呀。)
因此要用几何对象函数重复这个图形,则需要指定stat_summary。
ggplot(data = diamonds) +
geom_pointrange(
mapping = aes(x = cut, y = depth),
stat = "summary",
fun.ymin = min,
fun.ymax = max,
fun.y = median
)
8.位置调整-position
在直方图中,颜色映射是由color和fill之分的,表示边框和填充。如果要设置无填充(也就是透明),则fill=NA。NA在数据框里表示空值。
(1)直方图之堆叠式-fill
堆叠式就是在基础条形图上添加第三个变量,将这个变量映射给fill,就会在每个条形中分出不同颜色且不同比例的矩形。
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut,fill=clarity))
除了映射的方式以外,position参数设置位置调整功能。position="fill"也可以设置,但这样设置的每组堆叠条形具有相同的高度。
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "fill")
笔者补充:感觉这种堆叠方式并不如设置fill映射,因为他突出的是比例,每组之间数值的差异被忽略了。
(2)直方图之对象直接显示-identity
ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity)) +
geom_bar(alpha = 1/5, position = "identity")
ggplot(data = diamonds, mapping = aes(x = cut, colour = clarity)) +
geom_bar(fill = NA, position = "identity")
书中23页identity设置透明度和无填充的图是错的!
正确的是这样
(3)直方图之并列式-dodge
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "dodge")
(4)散点图之扰动-jitter
书中翻译为抖动,我认为扰动更精确。
以mpg的displ和hwy散点图为例
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
在这个例子中,数据有234行,图中却只有126个点。这就是因为有些点是重叠的,图上虽然显示一个点,但其实是好几个点重叠成了一个。
jitter可以为点添加随机扰动,使重叠的点分散开。
position参数设为jitter的快速实现:geom_jitter()
除了geom_jitter外,geom_point也可以展示重叠点,会根据重叠点的个数调整大小。
(5)stack-堆叠 无
ggplot(series, aes(time, value, group = type)) +
geom_line(aes(colour = type), position = "stack") +
geom_point(aes(colour = type), position = "stack")
ggplot(series, aes(time, value, group = type)) +
geom_line(aes(colour = type)) +
geom_point(aes(colour = type))
设置position_stack(上)和不设置(下)的区别:
9.坐标系
(1)coord_flip翻转坐标系
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot() +
coord_flip()
(2)coord_quickmap
为地图设置长宽比
此处需要加载maps包,否则会报错。
library(maps)
如果报错则:install.packages("maps")
library(maps)
nz <- map_data("nz")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black") +
coord_quickmap()
geom_polygon 是多边形图
(3)coord_polar 极坐标系
bar <- ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, fill = cut),
show.legend = FALSE,
width = 1
) +
theme(aspect.ratio = 1) +
labs(x = NULL, y = NULL)
bar + coord_flip()
bar + coord_polar()
ps:习题中涉及的
(1)关于饼图/牛眼图/圆圈图
ggplot(mpg, aes(x = factor(1), fill = drv)) +
geom_bar()
ggplot(mpg, aes(x = factor(1), fill = drv)) +
geom_bar(width = 1) +
coord_polar(theta = "y")
要点:
不分组,只有一个因子型变量drv。
如果作图不设置width,饼图中间会出现一个白色圈圈。经测试发现width等于几在图上并没有区别,但是不设置却不行。
theta是角度的意思。如果不设置这个参数就会得到牛眼图哈哈哈哈哈哈。
作者取名叫牛眼图
多圆圈图
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "fill") +
coord_polar(theta = "y")