Skip to main content
 首页 » 编程设计

介绍R语言新的数据结构 tibble

2022年07月19日129fff_TT

tibble 和 dplyr 包提供了对默认数据结构数据框的扩展,可以很方便实现对大数量处理任务。本文介绍tibble特点以及如何利用dplyr以统一方式处理数据。

tibble 介绍

tibble包括定义tibble为特定的数据框,它改变了标准数据框的一些行为。两者主要差异主要包括三点:

  • tibble 不会像数据框一样默认改变字符串列为因子类型;
  • tibble 对列的命名要求更宽松;
  • tibble 的打印方法对大数据集特别方便。

我们可以使用tibble() 函数创建Tibble类型数据:

library(tibble) 
dat <- tibble(TempCels = sample(-10:40, size=100, replace=TRUE), 
  TempFahr = TempCels*9/5 + 32, 
  Location = rep(letters[1:2] , each=50)) 
dat 
 
# A tibble: 100 x 3 
#  TempCels TempFahr Location 
#       <int>    <dbl> <chr>    
#  1        4     39.2 a        
#  2        2     35.6 a        
#  3       -5     23   a        
#  4        5     41   a        
#  5       15     59   a        
#  6      -10     14   a        
#  7       27     80.6 a        
#  8       -3     26.6 a        
#  9       15     59   a        
# 10        7     44.6 a        
# ... with 90 more rows 

该函数与标准的data.frame()函数类似,但每个列按顺序可以使用前面的列值,且字符向量不会自动转换为因子类型。

我们可以把数据框类型转为tibble类型。为了演示我们使用Iris数据集,该数据集包括150行5列信息的鸢尾花信息。

data("iris") 
dim(iris) 
class(iris) 
# Show in New WindowClear OutputExpand/Collapse Output 
# [1] 150   5 
# [1] "data.frame" 

上面示例首先载入iris数据,然后查看其维度和类型。虽然数据量不大,但如何你在控制台输入iris,会看到数据铺满了整个屏幕,如果tibble类型则不会,下面我们转换数据框至tibble类型:

library(tibble) 
ir <- as_tibble(iris) 
class(ir) 
# [1] "tbl_df"     "tbl"        "data.frame" 
ir 
# 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 
 

使用as_tibble() 函数创建tibble类型对象ir。需要说明的是,这里没有创建数据框的副本,因为网门看到新的对象仍然是data.frame类型,但同时也为"tbl_df" 和 “tbl” 类型。tbl_df为tibble类型,而第二种则是进一步的泛化,它可以独立于存储数据类型查看数据集。当打印tibble时,它并不像数据框一样沾满屏幕。当然你也可以给print()方法增加额外参数实现对数据框的输出:

 print(ir, n=Inf, width=Inf) 

Inf表示无穷大,即行和列展示都没有限制。

与数据框展示的另一个差异是,对于子集的数据展示,数据框有时展示子集会让人迷惑,请看示例:

 iris[1:15, "Petal.Length"] 
# Show in New WindowClear OutputExpand/Collapse Output 
# [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 
 class(iris[1:15, "Petal.Length"] ) 
# [1] "numeric" 

我们希望查看Petal.Length列的前15行记录,结果却为向量类型,取子集返回数据类型也改变了。这让很多人感到差异,虽然你可以通过下面代码获得期望的类型,但tibble从来不会让你差异:

iris[1:15, "Petal.Length", drop=FALSE] 
#    Petal.Length 
# 1           1.4 
# 2           1.4 
# 3           1.3 
# 4           1.5 
# 5           1.4 
# 6           1.7 
# 7           1.4 
# 8           1.5 
# 9           1.4 
# 10          1.5 
# 11          1.5 
# 12          1.6 
# 13          1.4 
# 14          1.1 
# 15          1.2 
 
ir[1:15, "Petal.Length"] 
 
# A tibble: 15 x 1 
#    Petal.Length 
#           <dbl> 
#  1          1.4 
#  2          1.4 
#  3          1.3 
#  4          1.5 
#  5          1.4 
#  6          1.7 
#  7          1.4 
#  8          1.5 
#  9          1.4 
# 10          1.5 
# 11          1.5 
# 12          1.6 
# 13          1.4 
# 14          1.1 
# 15          1.2 

tibble要想获得类似数据框的返回结果,可以先抽取列,然后再从列数据中选取需要的行:

ir$Petal.Length[1:15] 
# Show in New WindowClear OutputExpand/Collapse Output 
# [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 
# 或者使用中括号方式 
ir[["Petal.Length"]][1:15] 
# [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 

请注意,tibbles和数据帧之间的差异可能会使一些使用tibbles的包无效。如果这些包的函数在设置了单个列之后,以某种方式做了简化,那么就会出现这种情况。此时如果你传递tibble而不是数据帧,将不会得到预期的结果,并可能返回一些错误。如遇到这种情况,请使用标准数据框而不是tibble来调用这些函数。

dplyr 选择tibble数据

dplyr包定义了tbl类型,作为实际数据源的包装类型。它封装数据源病提供了一组统一的方法操作数据,该包当前支持的数据源包括:标准数据框(以tibbles的形式)、几个数据库管理系统以及其他数据源。其优势为:

  • 对数据源的封装
  • 提供统一的数据处理方法
  • 数据处理的计算效率高

总之,只要使用dplyr连接数据源创建tbl对象,几乎可以忽略该数据源,利用统一的独立数据源的方式处理数据。

dplyr提供了很多函数可以很容易处理tbl数据对象。这里仅简单展示如何查询数据,我们可以利用select() 和 filter() 函数实现,前者过滤列,后者过滤行。

假如我们需要查看setosa类型鸢尾花的花瓣长度和宽度,实现方式如下:

library(dplyr) 
 select(filter(ir,Species=="setosa"),Petal.Width, Petal.Length) 
  
# A tibble: 50 x 2 
#    Petal.Width Petal.Length 
#          <dbl>        <dbl> 
#  1         0.2          1.4 
#  2         0.2          1.4 
#  3         0.2          1.3 
#  4         0.2          1.5 
#  5         0.2          1.4 
#  6         0.4          1.7 
#  7         0.3          1.4 
#  8         0.2          1.5 
#  9         0.2          1.4 
# 10         0.1          1.5 
# ... with 40 more rows  
 
# view(select(filter(ir,Species=="setosa"),3:4)) 

有两点需要说明下,首先上面语句中,不是必须属于字段名称,我们可以直接使用 3:4 (3,4两列);其次,返回结果仅展示了一部分,如果我们需要查看全部信息可以使用view()函数,它会打开新的编辑器查看完整结果数据。

上面示例使用传统函数组合方式,函数组合方式功能强大,但代码不容易理解。dplyr提供管道操作方式使得代码更容易理解,请看示例:

filter(ir, Species == "setosa")  %>% select(3:4) 
 
# A tibble: 50 x 2 
#    Petal.Length Petal.Width 
#           <dbl>       <dbl> 
#  1          1.4         0.2 
#  2          1.4         0.2 
#  3          1.3         0.2 
#  4          1.5         0.2 
#  5          1.4         0.2 
#  6          1.7         0.4 
#  7          1.4         0.3 
#  8          1.5         0.2 
#  9          1.4         0.2 
# 10          1.5         0.1 
# ... with 40 more rows 
 
# ir %>% filter(Species == "setosa") %>% select(3:4)  
 

管道操作符非常简单直观,上面示例还可以写成 ir %>% filter(Species == "setosa") %>% select(3:4),它可以应用任何R的函数。其思想是左边函数的结果作为参数传给右边函数,x %>% f(y) 被转为 f(x,y)。显然这种方式比传统的函数式写法更好读、更自然、更符合我们的思维习惯。

总结

本文我们介绍了tibble类型。说明它与数据框的关系以及如何利用dplyr提供的统一方式操作数据。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/121615044
阅读延展