Rdata004 使用tibble实现简单数据框

1. tibble简介

tibble 是一种简单数据框,它对传统数据框的功能进行了一些修改,以便更易于使用。R 是一门古老的语言,其中有些功能在 10 年或 20 年前是适用的,但现在已经过时。在不破坏现有代码的前提下,很难修改 R 的基础功能,因此多数革新都是以扩展包的方式出现的。本章会介绍 tibble 包,其所提供的简单数据框更易于在 tidyverse 中使用。多数情况下,我们会交替使用 tibble 和数据框这两个术语;如果想要特别强调 R 内置的传统数据框,我们会使用 data.frame 来表示
如果读完本章后你还想学习有关 tibble 的更多知识,可以使用 vignette("tibble")命令。

2. 创建tibble

2.1 准备工作

tibble包是tidyverse的核心包之一

library(tidyverse)
2.2 创建
2.2.1 as_tibble()

tibble 是 tidyverse 的标准功能之一。由于多数其他 R 包使用的是标准数据框,因此你可能想要将数据框转换为 tibble。可以使
用 as_tibble() 函数来完成转换

as_tibble(iris) 
# # A tibble: 150 x 5
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1          5.1         3.5          1.4         0.2 setosa 
# 2          4.9         3            1.4         0.2 setosa 
# 3          4.7         3.2          1.3         0.2 setosa 
# 4          4.6         3.1          1.5         0.2 setosa 
# 5          5           3.6          1.4         0.2 setosa 
# 6          5.4         3.9          1.7         0.4 setosa 
# 7          4.6         3.4          1.4         0.3 setosa 
# 8          5           3.4          1.5         0.2 setosa 
# 9          4.4         2.9          1.4         0.2 setosa 
# 10         4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows

2.2.2 tibble()

可以通过 tibble() 函数使用一个向量来创建新 tibble。tibble() 会自动重复长度为 1 的输入,并可以使用刚刚创建的新变量

tibble(
  x=1:5,
  y=1,
  z=x*2+y
)

# # A tibble: 5 x 3
# x     y     z
# <int> <dbl> <dbl>
# 1     1     1     3
# 2     2     1     5
# 3     3     1     7
# 4     4     1     9
# 5     5     1    11

tibble() 函数的功能要少得多:它不能改变输入的类型(例如,不能将字符串转换为因子)、变量的名称,也不能创建行名称。
可以在 tibble 中使用在 R 中无效的变量名称(即不符合语法的名称)作为列名称。例如,列名称可以不以字母开头,也可以包含特殊字符(如空格)。要想引用这样的变量,需要使用反引号 ` 将它们括起来

tibble(`:)` = "smile",   
       ` ` = "space", 
       `2000` = "number")
# # A tibble: 1 x 3
#     `:)`  ` `   `2000`
#     <chr> <chr> <chr> 
#   1 smile space number
2.2.3 tribble()

创建 tibble 的另一种方法是使用 tribble() 函数,tribble 是 transposed tibble(转置 tibble)
的缩写。tribble() 是定制化的,可以对数据按行进行编码:列标题由公式(以 ~ 开头)定义,数据条目以逗号分隔,这样就可以用易读的方式对少量数据进行布局

tribble(
  ~x,~y,~z,
  #--/--/----
  "a",2,3.6,
  "b",1,8.5
)

# # A tibble: 2 x 3
#     x         y     z
#   <chr>    <dbl> <dbl>
#   1 a         2   3.6
#   2 b         1   8.5

3. 对比tibble与data.frame

tibble 和传统 data.frame 的使用方法主要有两处不同:打印和取子集

3.1 打印

tibble 的打印方法进行了优化,只显示前 10 行结果,并且列也是适合屏幕的,这种方式非常适合大数据集。除了打印列名,tibble 还会打印出列的类型,这项非常棒的功能借鉴于
str() 函数。

tibble(
  a = lubridate::now() + runif(1e3) * 86400,   b = lubridate::today() + runif(1e3) * 30,   c = 1:1e3, 
  d = runif(1e3), 
  e = sample(letters, 1e3, replace = TRUE) 
)

# # A tibble: 1,000 x 5
#    a                   b             c   d  e    
#   <dttm>              <date>     <int> <dbl> <chr>
# 1 2020-09-17 08:51:54 2020-09-29     1 0.828 y    
# 2 2020-09-17 00:52:46 2020-09-29     2 0.477 v    
# 3 2020-09-17 21:40:49 2020-09-19     3 0.455 h    
# 4 2020-09-17 05:41:40 2020-10-06     4 0.241 j    
# 5 2020-09-17 12:05:58 2020-09-28     5 0.898 t    
# 6 2020-09-17 19:20:18 2020-10-04     6 0.882 i    
# 7 2020-09-17 22:17:16 2020-09-25     7 0.446 j    
# 8 2020-09-17 19:54:45 2020-10-05     8 0.636 k    
# 9 2020-09-17 11:25:12 2020-09-28     9 0.496 s    
# 10 2020-09-17 02:16:04 2020-09-18    10 0.989 z    
# # ... with 990 more rows

在打印大数据框时,tibble 的这种设计避免了输出占满整个控制台。但有时需要比默认显示更多的输出,这时就要设置几个选项。首先,可以明确使用 print() 函数来打印数据框,并控制打印的行数(n)和显示的宽度(width)。width = Inf 可以显示出所有列

nycflights13::flights %>%
  print(n=10,width=Inf)

# # A tibble: 336,776 x 19
#   year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum origin dest  air_time distance  hour minute time_hour          
#   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl> <chr>    <int> <chr>   <chr>  <chr>    <dbl>    <dbl> <dbl>  <dbl> <dttm>             
# 1  2013     1     1      517            515         2      830            819        11 UA        1545 N14228  EWR    IAH        227     1400     5     15 2013-01-01 05:00:00
# 2  2013     1     1      533            529         4      850            830        20 UA        1714 N24211  LGA    IAH        227     1416     5     29 2013-01-01 05:00:00
# 3  2013     1     1      542            540         2      923            850        33 AA        1141 N619AA  JFK    MIA        160     1089     5     40 2013-01-01 05:00:00
# 4  2013     1     1      544            545        -1     1004           1022       -18 B6         725 N804JB  JFK    BQN        183     1576     5     45 2013-01-01 05:00:00
# 5  2013     1     1      554            600        -6      812            837       -25 DL         461 N668DN  LGA    ATL        116      762     6      0 2013-01-01 06:00:00
# 6  2013     1     1      554            558        -4      740            728        12 UA        1696 N39463  EWR    ORD        150      719     5     58 2013-01-01 05:00:00
# 7  2013     1     1      555            600        -5      913            854        19 B6         507 N516JB  EWR    FLL        158     1065     6      0 2013-01-01 06:00:00
# 8  2013     1     1      557            600        -3      709            723       -14 EV        5708 N829AS  LGA    IAD         53      229     6      0 2013-01-01 06:00:00
# 9  2013     1     1      557            600        -3      838            846        -8 B6          79 N593JB  JFK    MCO        140      944     6      0 2013-01-01 06:00:00
# 10 2013     1     1      558            600        -2      753            745         8 AA         301 N3ALAA  LGA    ORD        138      733     6      0 2013-01-01 06:00:00
# # ... with 336,766 more rows

可以通过设置以下选项来控制默认的打印方式

  • options(tibble.print_max = n, tibble.pring_min = m):如果多于 m 行,则只打印出 n行。options(tibble.print_min = Inf) 表示总是打印所有行。
  • options(tibble.width = Inf) 表示总是打印所有列,不考虑屏幕的宽度
3.2 取子集

迄今为止,你学到的所有工具都是作用于整个数据框。如果想要提取单个变量,那么就需要一些新工具,如 $[[[[可以按名称或位置提取变量;$只能按名称提取变量,但可以减少一些输入

# 按名称提取
mtcars$wt
# [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840 3.845 1.935 2.140 1.513 3.170 2.770 3.570 
# [32] 2.780

(wt <- mtcars[["wt"]])
# [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840 3.845 1.935 2.140 1.513 3.170 2.770 3.570 
# [32] 2.780

# 按位置提取
wt[[1]]
# [1] 2.62


# 要想在管道中使用这些提取操作,需要使用特殊的占位符 ".".
mtcars  %>% .$wt
# [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070 3.730 3.780 5.250 5.424 5.345 2.200 1.615
# [20] 1.835 2.465 3.520 3.435 3.840 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780
mtcars  %>% .[["wt"]]
# [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070 3.730 3.780 5.250 5.424 5.345 2.200 1.615
# [20] 1.835 2.465 3.520 3.435 3.840 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780

4 与旧代码进行交互

  • 有些比较旧的函数不支持 tibble。如果遇到这种函数,可以使用 as.data.frame() 函数将tibble 转换回 data.frame
  • 有些旧函数不支持 tibble 的主要原因在于 [ 的功能。本书没有使用太多的 [,因为dplyr::filter() 和 dplyr::select() 可以通过更加清晰的代码解决同样的问题。
  • 对于 R 基础包中的数据框,[ 有时返回一个数据框,有时返回一个向量。对于 tibble,[ 则总是返回另一个 tibble。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354