背景
我自学了2年多的R语言,也算是入了门。在可视化方面,不推荐初学者直接学ggplot2,虽然其画出来的图好看,但是他的数据组织方式和画图逻辑是没有编程和数据结构基础的人所不能理解的。我之前就无脑买了一本国内的ggplot2
教学的书,虽然其速成,但学会的只是改代码,真正到自己编符合自己需求的图的时候(离开了书),完全不会。也就是你出的图基本上就局限于书里的样子了。说实话ggplot这种奇怪画图逻辑的函数之所以会存在,完全是因为 tidyr
,reshape2
,dplur
这一系列数据科学包组成的一个数据分析生态,而ggplot2
是这个生态的最后一环——出图。所以一开始上来就最后一环怎么可能学得会?看似玩笑话,实则是很真实的。gather
函数就是其中一个数据组织变化的函数,也是难点之一。
gather函数介绍
gather
函数和spread
函数是tidy的黑白双星,他们起着完全相反的作用,一个是把数据tidy,另一个是把数据untidy,tidy没有一个具体的翻译,不太好解释。但是如果要用ggplot画图,数据就必须是tidy的。直接看例子吧!
> table4a
# A tibble: 3 × 3
country `1999` `2000`
* <chr> <int> <int>
1 Afghanistan 745 2666
2 Brazil 37737 80488
3 China 212258 213766
> table4b
# A tibble: 3 × 3
country `1999` `2000`
* <chr> <int> <int>
1 Afghanistan 19987071 20595360
2 Brazil 172006362 174504898
3 China 1272915272 1280428583
table4a是三个国家在1999、2000这两年的(非典)确诊数,table4b是这三个国家在1999、2000年的人口数。这个数据被称作untidy的数据,这种数据是不太方面进行ggplot函数画图和颜色渲染包(如[[ggsci]])的渲染的。利用gather函数可以将他们tidy了,那什么是tidy的数据呢?
table4a %>%
+ gather(`1999`,`2000`,key = "year", value = "cases")
# A tibble: 6 × 3
country year cases
<chr> <chr> <int>
1 Afghanistan 1999 745
2 Brazil 1999 37737
3 China 1999 212258
4 Afghanistan 2000 2666
5 Brazil 2000 80488
6 China 2000 213766
table4b %>%
+ gather(`1999`,`2000`,key = "year", value = "cases")
# A tibble: 6 × 3
country year cases
<chr> <chr> <int>
1 Afghanistan 1999 19987071
2 Brazil 1999 172006362
3 China 1999 1272915272
4 Afghanistan 2000 20595360
5 Brazil 2000 174504898
6 China 2000 1280428583
就是把原本表示一种数据(只是年份不同)的两列并到一列来,并且增加一列类别标识(这里就是year)。当然还可以是多列,比如增加了一个2001年等等的。spread是相反的作用,这里就不过多介绍。
用法
我常常遇到的数据处理问题是画图,例如下面这个例子是最近的作业中遇到的,我有三个指标是同样的单位,我想画到一张图里,但是数据是一个指标一列,每行是每天的数据,这就是典型的untidy数据。数据如下,我需要以ET_acum
、P_acum
、 ETeq_acum
分别为Y,以TIMESTAMP
为X画图。
DF_CN_Cha_subset %>%
+ select(ET_acum,P_acum,ETeq_acum,TIMESTAMP) %>%
+ head()
ET_acum P_acum ETeq_acum TIMESTAMP
1 0.02069014 0 0.09171932 2003-01-01
2 0.05281300 0 0.14481253 2003-01-02
3 0.18788817 0 0.21098686 2003-01-03
4 0.26333105 0 0.27798563 2003-01-04
5 0.33071178 0 0.35107005 2003-01-05
6 0.36026723 0 0.37868165 2003-01-06
其实有一种很笨的办法:
就是不tidy直接画,然后颜色自己一个个设置,代码如下:
df1%>%
ggplot(aes(x = TIMESTAMP, y = ET_acum)) +
geom_line(size = 1,color = "#f8766d") +
geom_line(size = 1,aes(y= ETeq_acum), color = "#00ba38") +
geom_line(size = 1,aes(y= P_acum), color = "#619cff") +
theme_classic()
画出来的图是没有图例的,应该也可以手动加,但我就不去学了(Y轴我也没改)。
这种方法,只能自己一个个手输颜色,如果有10类,你就得打10个geom_line()
,是不是很麻烦,而且。这个方法没图例,也不能使用scale_fill_XXX()
更好的方法就是先tidy再画,而且之后的ggplot函数就很简单,不仅自己有图例,而且可以使用R中的众多色版进行调色。刚刚我手动用的这三个颜色是R语言默认的三色画图的颜色,如果不设置,他就是三条黑线。这三个还是我用截屏工具识别的十六进制码。所以这也是不方便的一点。
df1%>%
gather('P_acum','ET_acum','ETeq_acum', key = 'type', value = 'value') %>%
ggplot(aes(x = TIMESTAMP, y = value, color = type)) +
geom_line(size= 1) +
theme_classic() +
scale_color_npg() +
scale_y_continuous('Cumulative ET,ETeq, P(mm)')
其中scale_color_npg()
是ggsci
提供的色板,来自NPG(Nature Publishing Group)也就是nature杂志的颜色。还提供了众多期刊的调色如AAAS,science杂志的的,只需改变一个函数就可以改变颜色。
以下是使用scale_color_aaas()
的图
当然有更多的类也是自动识别,自动上色的。但是这个包应该每种色版只有10个颜色。所以你有一个十个类以上的数据画图应该是用不了这个色板。
这是npg的10种颜色:
这是aaas的10种颜色:
以上就是这次分享的内容,如果觉得对你有帮助的话,求赞,求关注!很久没更新,是因为很久没做事了!
👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼👼