ggplot2读书笔记12:第九章 数据分析

第九章介绍了ggplot2在数据分析中的应用,重点讲解了数据整理的原则,包括Tidy Data的概念。内容涵盖如何使用R包如`tidyr`进行数据整理,如Spread和Gather操作,以及Separate和Unite函数的应用,帮助将数据转换为适合可视化的格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本书的最后一个部分,Part III,Data Analysis。主要包括三个章节,今天先来看第九章:

Data Analysis

9.1 简介

在前面的学习中,我们使用的模拟数据集都是已经整理好的数据框,可以直接使用。但通常实际数据并不会这么理想,需要通过一定的整理好变换才能用于作图

所以这个部分的目标就是把ggplot2和其他工具结合起来,用于完整的数据分析。

  • 首先学习整理数据的原则,了解dplyr以及tidyr等可以用于整理凌乱数据集的R包
  • 大多数可视化需要进行数据转换,可能要在现有变量的基础上,创造新的变量;或者执行简单的聚合。这些在第十章中有详细说明。
  • 使用R建模的过程中,如何将模型转换成整洁的数据集,这些在第十一章中可以稍作了解。

在本章中,作者用了两个事例来介绍怎样整理数据。

9.2 整理数据(Tidy Data)

整理数据的原则很简单:用一致的方式存储数据。(storing your data in a consistent way)

所以整理数据的目的是为了创造一个数据框的统计学结构(变量和观测数据)和物理结构(列和行)之间的映射。

其中,

变量放在中(Variables go in columns)

观测数据放在中(Observations go in rows)

我们需要先安装几个R包,dplyrtidyrmagrittr

下面加载一个需要整理的关于经济学失业率economics数据集的子集ec2,作为例子:

> ec2
# A tibble: 12 x 11
   month `2006` `2007` `2008` `2009` `2010` `2011` `2012` `2013` `2014` `2015`
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
 1  1.00   8.60   8.30   9.00   10.7   20.0   21.6   21.0   16.2   15.9   13.4
 2  2.00   9.10   8.50   8.70   11.7   19.9   21.1   19.8   17.5   16.2   13.1
 3  3.00   8.70   9.10   8.70   12.3   20.4   21.5   19.2   17.7   15.9   12.2
 4  4.00   8.40   8.60   9.40   13.1   22.1   20.9   19.1   17.1   15.6   11.7
 5  5.00   8.50   8.20   7.90   14.2   22.3   21.6   19.9   17.0   14.5   NA  
 6  6.00   7.30   7.70   9.00   17.2   25.2   22.3   20.1   16.6   13.2   NA  
 7  7.00   8.00   8.70   9.70   16.0   22.3   22.0   17.5   16.3   13.5   NA  
 8  8.00   8.40   8.80   9.70   16.3   21.0   22.4   18.5   16.8   13.3   NA  
 9  9.00   8.00   8.70  10.2    17.8   20.3   22.0   18.8   16.5   13.3   NA  
10 10.0    7.90   8.40  10.4    18.9   21.2   20.5   19.7   16.1   13.5   NA  
11 11.0    8.30   8.60   9.80   19.8   21.0   20.9   18.5   17.0   12.8   NA  
12 12.0    7.50   8.40  10.5    20.1   21.9   20.5   17.6   17.0   12.6   NA  

PS. 这个ec2不是ggplot2中自带的数据集,无法直接加载出来,通过万能的Google找到了加载ec2的方法,在此之前我们需要再多安装一个用于时间数据处理的r包lubridate

library(lubridate)
library(magrittr)
library(dplyr)
library(tidyr)

ec2 <- 
  ggplot2::economics %>% 
  tbl_df() %>%
  transmute(year = year(date), month = month(date), rate = uempmed) %>%
  filter(year > 2005) %>%
  spread(year, rate)
ec2

这个数据集的混乱之处在于,变量yearmonth分别是列名和行名,观测结果在每个小单元里。

然后我们需要用两对工具:

  • Spread & gather
  • Separate & unite

9.3 Spread and Gather

先看一下这俩表格有啥区别:

> indexed <- data.frame(
+   x = c("a", "b", "c", "d", "c"),
+   y = c("A", "D", "A", "C", "B"),
+   z = c(1, 5, 4, 9, 10)
+ ) %>% arrange(x, y)
> matrix <- indexed %>% spread(y, z)
> 
> knitr::kable(indexed)

|x  |y  |  z|
|:--|:--|--:|
|a  |A  |  1|
|b  |D  |  5|
|c  |A  |  4|
|c  |B  | 10|
|d  |C  |  9|
> knitr::kable(matrix)

|x  |  A|  B|  C|  D|
|:--|--:|--:|--:|--:|
|a  |  1| NA| NA| NA|
|b  | NA| NA| NA|  5|
|c  |  4| 10| NA| NA|
|d  | NA| NA|  9| NA|

(这里面用到了一个表格生成函数knitr::kable())

这两种表格分别称为“索引数据”(通过变量值查找数据)和“笛卡尔数据”(通过查看行和列的交集来找到一个值)

tidyr包包含两个函数gather()spread() 可以用来执行以下操作:

  • gathering:从笛卡尔数据翻译成索引数据

  • spreading:从索引数据翻译成笛卡尔数据

Gather

gather()函数包含以下四个参数:

  • data:需要转换的数据集
  • key:将从列名创建出的变量名称
  • value:将从每个单元创建出的变量名
  • ...:要收集哪些变量,可以一个一个列出来,也可以使用简写形式..:..

所以我们要整理上面的ec2数据集,就要把所有变量放在列中。其中只有month在列中,yearrate还是“笛卡尔数据形式”,所以我们要把他们转换成“索引形式”,可生成以下数据集:

注意2006-2015不是R语言中标准的变量名称(不是以字母开头)所以我们需要用单括号括起来

> gather(ec2, key = year, value = unemp, `2006`:`2015`)
# A tibble: 120 x 3
   month year  unemp
   <dbl> <chr> <dbl>
 1  1.00 2006   8.60
 2  2.00 2006   9.10
 3  3.00 2006   8.70
 4  4.00 2006   8.40
 5  5.00 2006   8.50
 6  6.00 2006   7.30
 7  7.00 2006   8.00
 8  8.00 2006   8.40
 9  9.00 2006   8.00
10 10.0  2006   7.90
# ... with 110 more rows

另一种方法(gather除了month之外的数据):

gather(ec2, key = year, value = unemp, -month)

增加两种参数,可以更加严谨:

economics_2 <- gather(ec2, year, rate, `2006`:`2015`, 
                      convert = TRUE, na.rm = TRUE)
economics_2

其中

convert = TRUE自动将年份从字符串转换为数字

na.rm = TRUE自动删除没有数据的月份

当数据处于这种形式时,比较容易可视化:

library(ggplot2)

ggplot(economics_2, aes(month, rate, group = year)) +
  geom_line(aes(colour = year), size = 1)

image

ggplot(economics_2, aes(year + (month - 1) / 12, rate)) +
  geom_line()

image

Spread

spread()是与gather()相对应的另一种函数。

如下例,创建weather数据集,包含三个变量,分别是day, raintemp

weather <- dplyr::data_frame(
  day = rep(1:3, 2),
  obs = rep(c("temp", "rain"), each = 3),
  val = c(c(23, 22, 20), c(0, 0, 5))
)

输出如下“索引模式”

> weather
# A tibble: 6 x 3
    day obs     val
  <int> <chr> <dbl>
1     1 temp  23.0 
2     2 temp  22.0 
3     3 temp  20.0 
4     1 rain   0   
5     2 rain   0   
6     3 rain   5.00

通过spread()可以将繁琐的索引数据转变成简洁的笛卡尔数据形式。

参数和gather()类似,如下例:

> spread(weather, key = obs, value = val)
# A tibble: 3 x 3
    day  rain  temp
  <int> <dbl> <dbl>
1     1  0     23.0
2     2  0     22.0
3     3  5.00  20.0

9.4 Separate and Unite

当多个变量被放在了一列中,或者很多列中有一个变量时,我们使用separate()unite()函数。

如下例:

trt <- dplyr::data_frame(
  var = paste0(rep(c("beg", "end"), each = 3), "_", rep(c("a", "b", "c"))),
  val = c(1, 4, 2, 10, 5, 11)
)

数据集中包含三个变量(time, treatment
和 value),但是time和treatment混在了同一列中:

> trt
# A tibble: 6 x 2
  var     val
  <chr> <dbl>
1 beg_a  1.00
2 beg_b  4.00
3 beg_c  2.00
4 end_a  10.0 
5 end_b  5.00
6 end_c  11.0

separate()函数包括:

  • data:要修改的数据框
  • col:要分隔的列
  • into:给新变量命名的字符向量
  • sep:描述如何分开这些变量

在上面的例子中:

> separate(trt, var, c("time", "treatment"), "_")
# A tibble: 6 x 3
  time  treatment   val
  <chr> <chr>     <dbl>
1 beg   a          1.00
2 beg   b          4.00
3 beg   c          2.00
4 end   a          10.0 
5 end   b          5.00
6 end   c          11.0 

unite()separate()的反函数,但并不常用。


参考资料:

  1. Hadley Wickham(2016). ggplot2. Springer International Publishing. doi: 10.1007/978-3-319-24277-4
  2. 《R语言应用系列丛书·ggplot2:数据分析与图形艺术》
  3. https://github.com/hadley/ggplot2-book/blob/master/tidy-data.rmd

——————-我是求关注的分界线————–

更多R语言、可视化作图ggplot2包学习笔记请关注微信公众号:

image

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值