tibble

1. tibble introduction

tibble是R语言中一个用来替换data.frame类型的扩展的数据框,tibble继承了data.frame,是弱类型的,同时与data.frame有相同的语法,使用起来更方便。tibble包,也是由Hadley开发的R包。

tibble对data.frame做了重新的设定:

  • tibble,不关心输入类型,可存储任意类型,包括list类型

  • tibble,没有行名设置 row.names

  • tibble,支持任意的列名

  • tibble,会自动添加列名

  • tibble,类型只能回收长度为1的输入

  • tibble,会懒加载参数,并按顺序运行

  • tibble,是tbl_df类型

2. tibble Installation

# The easiest way to get tibble is to install the whole tidyverse:
install.packages("tidyverse")

# Alternatively, install just tibble:
install.packages("tibble")

# Or the the development version from GitHub:
# install.packages("devtools")
devtools::install_github("tidyverse/tibble")

3. tibble usage

对于tibble包的使用,主要需掌握创建、数据转型、数据查看、数据操作、与data.frame的区别点。复杂的数据处理功能,由dplyr项目来完成

3.1 创建tibble

创建一个tibble类型的data.frame非常简单,语法与传统的data.frame类似。

# 创建一个data.frame
d1 <- data.frame(1:5,b=LETTERS[1:5])
d1 
##    X1.5 b
## 1      1 A
## 2      2 B
## 3      3 C
## 4      4 D
## 5      5 E
# 创建一个tibble类型的data.frame
t1 <- tibble(1:5,b=LETTERS[1:5])
t1
## # A tibble: 10 x 2
##    `1:5`     b
##     <int> <chr>
##  1      1     A
##  2      2     B
##  3      3     C
##  4      4     D
##  5      5     E

从上面的输出可以看到tibble类型,会在输出时多一行,用来指定每一列的类型。

tibble用缩写定义了7种类型:

  • int,代表integer

  • dbl,代表double

  • chr,代表character向量或字符串

  • dttm,代表日期+时间(a date + a time)

  • lgl,代表逻辑判断TRUE或者FALSE

  • fctr,代表因子类型factor

  • date,代表日期dates

查看类型,发现tbl_df继承了tbl继承是data.frame,所以tibble是data.frame的子类型。

class(d1)  # d1为data.frame类型
## [1] "data.frame"
class(t1)  # t1为tbl_df类型
## [1] "tbl_df"     "tbl"        "data.frame"
is.tibble(t1)  # 判断是不是tibble类型
## [1] TRUE
attributes(t1)  # 查看t1的属性
## $names
## [1] "1:5" "b"   
## 
## $class
## [1] "tbl_df"     "tbl"        "data.frame"
## 
## $row.names
##  [1]  1  2  3  4  5 
str(t1)  # 查看t1的静态结构
## Classes 'tbl_df', 'tbl' and 'data.frame':	5 obs. of  2 variables:
##  $ 1:5: int  1 2 3 4 5
##  $ b   : chr  "A" "B" "C" "D" ...

通过文本排列创建tibble

# tribble: 智能行(Row-wise)创建tibble
tribble(
~colA, ~colB,
"a",   1,
"b",   2,
"c",   3)
## # A tibble: 3 x 2
##    colA  colB
##   <chr> <dbl>
## 1     a     1
## 2     b     2
## 3     c     3

通过vector创建tibble

tibble(letters[1:8])
## # A tibble: 8 x 1
##   `letters[1:8]`
##            <chr>
## 1              a
## 2              b
## 3              c
## 4              d
## 5              e
## 6              f
## 7              g
## 8              h

通过list创建tibble

tibble(x = list(diag(1), diag(2)))
## # A tibble: 2 x 1
##               x
##          <list>
## 1 <dbl [1 x 1]>
## 2 <dbl [2 x 2]>

通过data.frame创建tibble, 或者通过一个tibble创建另一个tibble, 会报错

tibble(data.frame(1:5))
tibble(x = tibble(1, 2, 3))
## Error: Column `x` must be a 1d atomic vector or a list

tibble其实是存储list类型,这是data.frame做不到的。

3.2 数据类型转换

tibble是一个新的类型,R语言中大部分的数据都是基于原有的数据类型,所以原有数据类型与tibble类型的转换非常重要。

tibble类型是非常友好的,可以与data.frame, list, matrix 进行相互转型操作。tibble与vector不能进行直接转型,这与data.frame的行为一致,如果需要转型,可以分别取出每一列进行拼接,或转为matrix再操作。

tibble与data.frame的转型 是非常平滑的,一个转型函数就够,不需要中间做任何的特殊处理。

d2 <- as.tibble(d1)  # 把data.frame转型为tibble
d2
## # A tibble: 5 x 2
##    X1.5      b
##   <int> <fctr>
## 1     1      A
## 2     2      B
## 3     3      C
## 4     4      D
## 5     5      E
as.data.frame(d2)  # 再转回data.frame
##   X1.5 b
## 1    1 A
## 2    2 B
## 3    3 C
## 4    4 D
## 5    5 E

tibble与list的转型 也是非常平滑的,一个转型函数就够。

df <- as.tibble(list(x = 1:500, y = runif(500), z = 500:1)) # 把list转型为tibble
df
## # A tibble: 500 x 3
##        x         y     z
##    <int>     <dbl> <int>
##  1     1 0.8495452   500
##  2     2 0.7618803   499
##  3     3 0.2777375   498
##  4     4 0.2526940   497
##  5     5 0.5113623   496
##  6     6 0.4388692   495
##  7     7 0.9790384   494
##  8     8 0.9115946   493
##  9     9 0.2533256   492
## 10    10 0.8666731   491
## # ... with 490 more rows
str(as.list(df)) # 把tibble再转为list
## List of 3
##  $ x: int [1:500] 1 2 3 4 5 6 7 8 9 10 ...
##  $ y: num [1:500] 0.85 0.762 0.278 0.253 0.511 ...
##  $ z: int [1:500] 500 499 498 497 496 495 494 493 492 491 ...

tibble与matrix的转型 也是非常平滑的,一个转型函数就够。

m <- matrix(rnorm(15), ncol = 5) # 生成一个matrix
df <- as.tibble(m)  # matrix转为tibble
df
## # A tibble: 3 x 5
##          V1         V2         V3         V4         V5
##       <dbl>      <dbl>      <dbl>      <dbl>      <dbl>
## 1 0.5118629  0.5878416  0.1326850 -0.4349186 -0.4230024
## 2 1.4946800 -2.4883066 -0.2714426 -1.2485644  0.4272643
## 3 0.4299499  0.0667462 -0.3266860  1.0473085  0.2667502
as.matrix(df)  # tibble转为matrix
##             V1         V2         V3         V4         V5
## [1,] 0.5118629  0.5878416  0.1326850 -0.4349186 -0.4230024
## [2,] 1.4946800 -2.4883066 -0.2714426 -1.2485644  0.4272643
## [3,] 0.4299499  0.0667462 -0.3266860  1.0473085  0.2667502

vector可以转型为tibble类型,但是不能再转回vector了。

x <- as.tibble(1:5)  # vector转型到tibble
x
## # A tibble: 5 x 1
##   value
##   <int>
## 1     1
## 2     2
## 3     3
## 4     4
## 5     5
as.vector(x)  # tibble转型到vector, 不成功
## # A tibble: 5 x 1
##   value
##   <int>
## 1     1
## 2     2
## 3     3
## 4     4
## 5     5

3.3 tibble数据查询和取出

数据查询

通常用str()函数来观察数据的静态组成结果,tibble包提供了glimpse(),可以方便我们来观察tibble和data.frame类型的数据。

glimpse(mtcars)  # glimpse()对data.frame的数据查看输出
## Observations: 32
## Variables: 11
## $ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19....
## $ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, ...
## $ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 1...
## $ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, ...
## $ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.9...
## $ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3...
## $ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 2...
## $ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, ...
## $ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, ...
## $ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, ...
## $ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, ...
str(mtcars)  # str()对data.frame的数据查看输出
## 'data.frame':	32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
df <- tibble(x = rnorm(500), y = rep(LETTERS[1:25],20))  # 新建tibble
glimpse(df)  # glimpse()对tibble的数据查看输出
## Observations: 500
## Variables: 2
## $ x <dbl> 0.518404287, 0.097806751, 1.045576809, -1.214969437, 0.06113...
## $ y <chr> "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", ...
str(df)  # str()对tibble的数据查看输出
## Classes 'tbl_df', 'tbl' and 'data.frame':	500 obs. of  2 variables:
##  $ x: num  0.5184 0.0978 1.0456 -1.215 0.0611 ...
##  $ y: chr  "A" "B" "C" "D" ...

按列出数据

df <- tibble(x = 1:3, y = 3:1)

df[1]   # 一层[]返回的结果还是tibble
## # A tibble: 3 x 1
##       x
##   <int>
## 1     1
## 2     2
## 3     3
df[[1]]   # 二层[]与$返回的结果为列组成的向量
## [1] 1 2 3
df$x    # 二层[]与$返回的结果为列组成的向量
## [1] 1 2 3

按行取数据,用,来做分隔符

df[1,]  # 取第一行,返回的结果还是tibble
## # A tibble: 1 x 2
##       x     y
##   <int> <int>
## 1     1     3
df[1:2,]  # 取前2行,返回的结果还是tibble
## # A tibble: 2 x 2
##       x     y
##   <int> <int>
## 1     1     3
## 2     2     2
df[2:3,2]  # 取第二列的2,3行, 返回的结果还是tibble
## # A tibble: 2 x 1
##       y
##   <int>
## 1     2
## 2     1
df[2:3, ]$y  # 取第二列的2,3行, 返回的结果为列组成的向量
## [1] 2 1

3.4 tibble数据增加行和列

add_column(df, z = -1:1, w = 0)  # 增加列。默认加入最后一列后面,但是可以用.before和.after参数指定要插入列的位置
## # A tibble: 3 x 4
##       x     y     z     w
##   <int> <int> <int> <dbl>
## 1     1     3    -1     0
## 2     2     2     0     0
## 3     3     1     1     0
add_row(df, x = 99, y = 9)  # 增加行。默认加入最后一行后面
## # A tibble: 4 x 2
##       x     y
##   <dbl> <dbl>
## 1     1     3
## 2     2     2
## 3     3     1
## 4    99     9
add_row(df, x = 99, y = 9, .before = 2) # 在特定位置加入行,加入第二行前面
## # A tibble: 4 x 2
##       x     y
##   <dbl> <dbl>
## 1     1     3
## 2    99     9
## 3     2     2
## 4     3     1
add_row(df, x = 99, y = 9, .after = 2) # 在特定位置加入行,加入第二行后面
## # A tibble: 4 x 2
##       x     y
##   <dbl> <dbl>
## 1     1     3
## 2     2     2
## 3    99     9
## 4     3     1

3.5 tibble与data.frame的区别

列名,可以自由定义,并且会自动补全

tb <- tibble(
   `:)` = "smile",
   ` ` = "space",
   `2000` = "number",
   `列名` = "hi",
   1,1L)
tb
## # A tibble: 1 x 6
##    `:)`   ` ` `2000`  列名   `1`  `1L`
##   <chr> <chr>  <chr> <chr> <dbl> <int>
## 1 smile space number    hi     1     1

数据,按顺序执行懒加载

a <- 1:5
tibble(a, b = a * 2)
## # A tibble: 5 x 2
##       a     b
##   <int> <dbl>
## 1     1     2
## 2     2     4
## 3     3     6
## 4     4     8
## 5     5    10

打印输出控制,tibble的打印控制被重写了,所以执行print()函数时,模型会先进行类型匹配,然后调用print.tbl()。

tb <- tibble(a=1:5, b = a * 2, c=NA, d='a', e=letters[1:5]) # 创建tiblle
print(tb, n = 10, width = Inf)  # 打印前10行,不限宽度
## # A tibble: 5 x 5
##       a     b     c     d     e
##   <int> <dbl> <lgl> <chr> <chr>
## 1     1     2    NA     a     a
## 2     2     4    NA     a     b
## 3     3     6    NA     a     c
## 4     4     8    NA     a     d
## 5     5    10    NA     a     e
print(tb,n = 3, width = 30)  # 打印前3行,宽度30
## # A tibble: 5 x 5
##       a     b     c     d
##   <int> <dbl> <lgl> <chr>
## 1     1     2    NA     a
## 2     2     4    NA     a
## 3     3     6    NA     a
## # ... with 2 more rows, and 1
## #   more variables: e <chr>
df <- data.frame(tb); print(df)  # 用print函数,打印data.frame
##   a  b  c d e
## 1 1  2 NA a a
## 2 2  4 NA a b
## 3 3  6 NA a c
## 4 4  8 NA a d
## 5 5 10 NA a e

3.7 特殊的函数

lst—创建一个具有tibble特性的list。 lst函数的工作原理,类似于执行[list()]的操作。

lst(n = 5, x = runif(n))  #  创建一个list,懒加载,顺序执行
## $n
## [1] 5
## 
## $x
## [1] 0.8106662 0.9566540 0.7682681 0.9927918 0.1410948

enframe—快速创建tibble。enframe提供了一个模板,只有2列: name和value,快速地把2个向量匹配到tibble中,可以按行生成或按列生成。

enframe(1:3)  # 按列生成
## # A tibble: 3 x 2
##    name value
##   <int> <int>
## 1     1     1
## 2     2     2
## 3     3     3
enframe(c(a = 5, b = 7))  # 按行生成
## # A tibble: 2 x 2
##    name value
##   <chr> <dbl>
## 1     a     5
## 2     b     7

deframe—把tibble反向转成向量。默认把name列为索引,用value为值。

df <- enframe(c(a = 5, b = 7))  # 生成tibble
df
## # A tibble: 2 x 2
##    name value
##   <chr> <dbl>
## 1     a     5
## 2     b     7
deframe(df)  # 转为vector
## a b 
## 5 7

3.8 用于处理data.frame函数

df <- data.frame(x = 1:3, y = 3:1)  # 创建data.frame
has_name(df,'x')  # 判断是否有叫x的列
## [1] TRUE
has_rownames(df)  # 判断是否有行名
## [1] FALSE
row.names(df) <- LETTERS[1:3]  # 给df增加行名
df  
##   x y
## A 1 3
## B 2 2
## C 3 1
has_rownames(df)  # 判断是否有行名
## [1] TRUE
remove_rownames(df)  # 去掉行名
##   x y
## 1 1 3
## 2 2 2
## 3 3 1
df2<-rownames_to_column(df, var = "rowname")  # 把行名转换为单独的一列
df2
##   rowname x y
## 1       A 1 3
## 2       B 2 2
## 3       C 3 1
column_to_rownames(df2, var = "rowname")  # 把一列设置为行名
##   x y
## A 1 3
## B 2 2
## C 3 1
rowid_to_column(df, var = "rowid")  # 把行索引转换为单独的一列
##   rowid x y
## 1     1 1 3
## 2     2 2 2
## 3     3 3 1

References

tibble website
R语言数据科学新类型tibble

CHENYUAN

CHENYUAN

CHENYUAN
Pursuing the dream and the best future

CHENYUAN Blog Homepage

因为不想遗忘! 在这个信息大爆炸的年代,最重要的是对知识的消化-吸收-重铸。每天学了很多东西,但是理解的多少,以及能够运用多少是日后成功的关键。作为一个PhD,大脑中充斥了太多的东西,同时随着年龄的增长,难免会忘掉很多事情。所以只是为了在众多教程中写一个自己用到的,与自己...… Continue reading