2  tibble 数据

2.1 整洁数据

在浩如烟海的数据类型中,有一种数据类型特别为统计学家所关注。这一类数据有如下特点:

  1. 每行是一个个案(case)、个体(individual)、观测点(observation)、分析单位(unit of analysis)
    • 统计上讲,这些概念等价
  2. 每列是一个变量(variable)、特征(feature)
  3. 每格是一个取值(value),即某个个案的某条特征

这一类数据,有一种说法是整洁数据(tidy data),和其他五花八门的杂乱数据(messy data)相对。

整洁数据的结构非常清晰,通过行和列,可以锁定每个格子数值的含义。

下面是一些整洁数据的示例:

一、starwars 星球大战角色数据(87行,14列)
name height mass hair_color skin_color eye_color birth_year sex
Luke Skywalker 172 77 blond fair blue 19.0 male
C-3PO 167 75 NA gold yellow 112.0 none
R2-D2 96 32 NA white, blue red 33.0 none
Darth Vader 202 136 none white yellow 41.9 male
Leia Organa 150 49 brown light brown 19.0 female
Owen Lars 178 120 brown, grey light blue 52.0 male
二、billboard 歌曲榜单数据(79行,317列)
artist track date.entered wk1 wk2 wk3 wk4 wk5
2 Pac Baby Don’t Cry (Keep… 2000-02-26 87 82 72 77 87
2Ge+her The Hardest Part Of … 2000-09-02 91 87 92 NA NA
3 Doors Down Kryptonite 2000-04-08 81 70 68 67 66
3 Doors Down Loser 2000-10-21 76 76 72 69 67
504 Boyz Wobble Wobble 2000-04-15 57 34 25 17 17
98^0 Give Me Just One Nig… 2000-08-19 51 39 34 26 26
三、diamonds 钻石数据(53940行,10列)
carat cut color clarity depth table price x y z
0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48

2.2 tidyverse

本文是对 tidyverse 的入门介绍。

tidyverse (直译为``整洁宇宙’’)整合了一系列主要处理、分析整洁数据的R包(R packages)。每个包里面都有大量的函数。其特点是函数的命名、语法、用法非常整洁统一。

# 加载 tidyverse 包
library(tidyverse)
Warning: package 'ggplot2' was built under R version 4.3.3
Warning: package 'stringr' was built under R version 4.3.2
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::extract()   masks magrittr::extract()
✖ dplyr::filter()    masks stats::filter()
✖ dplyr::lag()       masks stats::lag()
✖ purrr::set_names() masks magrittr::set_names()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
提示

在载入 tidyverse 时,可能会出现类似上面的一些警告语,它们不会影响 tidyverse 的正常使用,请无须担心。

tidyverse 为整洁数据设计了一种数据格式,叫作 tibble。这个词是 tidy 和 table 的结合,顾名思义,特指整洁数据。它相当于Excel里的表格(整洁的才行)、Stata 里的数据、Python 里的 Pandas 数据框等。

在数据科学中,整洁数据是最主流的数据形式。尽管我们日常生活中,可以看到形形色色的数据呈现形式(比如12306列车时间表、网购的商品列表等),但是它们的底层数据都是很整洁的。

2.3 打印 tibble

在接下来的几章,我将以 diamonds 钻石数据为示例数据。

diamonds # 打印数据
# A tibble: 53,940 × 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.29 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
# ℹ 53,930 more rows

在R的界面中,tibble 数据的输出格式会像上面这样。从上到下,

  • # A tibble: 10 × 10 表示当前 tibble 共有10行、10列
  • carat cut ... 这一行是变量名
  • <dbl> <ord> ... 这一行是变量类型,比如
    • 数值型(<dbl>
    • 整数型(<int>
    • 有序类别型(<ord>
  • 1 1.5 Very Good 从这一行开始,都是钻石的具体数据了
    • 1为行号,其他均为这颗钻石的参数

如果你的 tibble 比较大,有很多行、很多列,tibble 在打印时会自动帮你隐藏多余的行和列,比方说

starwars
# A tibble: 87 × 14
   name     height  mass hair_color skin_color eye_color birth_year sex   gender
   <chr>     <int> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
 1 Luke Sk…    172    77 blond      fair       blue            19   male  mascu…
 2 C-3PO       167    75 <NA>       gold       yellow         112   none  mascu…
 3 R2-D2        96    32 <NA>       white, bl… red             33   none  mascu…
 4 Darth V…    202   136 none       white      yellow          41.9 male  mascu…
 5 Leia Or…    150    49 brown      light      brown           19   fema… femin…
 6 Owen La…    178   120 brown, gr… light      blue            52   male  mascu…
 7 Beru Wh…    165    75 brown      light      blue            47   fema… femin…
 8 R5-D4        97    32 <NA>       white, red red             NA   none  mascu…
 9 Biggs D…    183    84 black      light      brown           24   male  mascu…
10 Obi-Wan…    182    77 auburn, w… fair       blue-gray       57   male  mascu…
# ℹ 77 more rows
# ℹ 5 more variables: homeworld <chr>, species <chr>, films <list>,
#   vehicles <list>, starships <list>

在这里,

  • # ℹ 77 more rows 表示省略了77行
  • # ℹ 5 more variables: homeworld <chr>, ... 表示省略了5个变量,并列出了省略的变量名、变量类型

请注意,这里打印时省略的变量和个案,不影响数据本身的完整。

2.4 列的性质

从上面可以看到,同样省略了一些行和列,tibble 打印了变量名、变量类型等信息,却丝毫不介绍省略的其他个案。这是为什么呢?

在整洁数据中,相对于行,列(变量)有一些特殊的性质:

  1. 每一列都有名称(变量名)
    • 姓名是 name
    • 身高是 height
  2. 每一列只能储存同种类型的数值,不能“混搭”,比方说
    • 姓名是文本型(chr
    • 身高是整数型(int
  3. 每一列都可以统计
    • A开头姓名的比例(约5.7%
    • 身高高于170吗?
代码
# 仅供参考,不需要掌握
starwars %>%
  summarise(
    percentage = sprintf(
      "%.1f%%",
      mean(str_detect(name, "^A")) * 100
    )
  )
# A tibble: 1 × 1
  percentage
  <chr>     
1 5.7%      

这里统计了A开头姓名的比例约为5.7%

代码
# 仅供参考,不需要掌握
starwars %>%
  transmute(
    height,
    `height > 170` = height > 170
  )
# A tibble: 87 × 2
   height `height > 170`
    <int> <lgl>         
 1    172 TRUE          
 2    167 FALSE         
 3     96 FALSE         
 4    202 TRUE          
 5    150 FALSE         
 6    178 TRUE          
 7    165 FALSE         
 8     97 FALSE         
 9    183 TRUE          
10    182 TRUE          
# ℹ 77 more rows

这里判断了各个角色的身高有没有高于170,判断结果为TRUEFALSE

整理成表格如下:

列(变量) 行(个案)
必须起名(具名性) 不需要
一定同类(同质性) 不一定
可以统计(算术性) 不可以

2.5 列的类型

列,或者``变量’’,在 R 里面用向量(矢量,vector)来存储。下面介绍一些常见的变量类型:

  1. 数值型(numeric),包括实数型(double, real)和整数型(integer)
  2. 逻辑型(logical),包括 TRUE 和 FALSE
  3. 字符型(character),包括各种长度的文本
  4. 类别型(factor)、标签型(haven label),通常是数值型变量加上标签
  5. 日期型(date)、日期时间型(datetime),本质是数值型
  6. 几何型(geometry),来自 sf 包,包括点、线、面等,用于空间分析和画图
  7. 其他一维对象
  8. 二维乃至多维对象,比如一列 tibbles,每个单元格存储一个 tibble