跳到内容

arrow 包提供了用于将单个数据文件读取到内存中的函数,支持多种常见格式。 默认情况下,调用这些函数中的任何一个都会返回一个 R 数据框。 要返回 Arrow Table,请设置参数 as_data_frame = FALSE

对于将数据写入单个文件,arrow 包提供了以下函数,这些函数可以与 R 数据框和 Arrow 表一起使用

所有这些函数都可以在本地文件系统或云存储中读取和写入文件。 有关 arrow 中云存储支持的更多信息,请参阅云存储文章

arrow 包还支持读取大于内存的单个数据文件,以及读取和写入多文件数据集。 这使得能够分析和处理大于内存的数据,并提供将数据分区为更小的块而无需将完整数据加载到内存中的能力。 有关此主题的更多信息,请参阅数据集文章

Parquet 格式

Apache Parquet 是存储分析数据的常用选择;它是一种二进制格式,经过优化,可减少文件大小并提高读取性能,尤其是对于基于列的访问模式。 使用 arrow 读取和写入 Parquet 数据的最简单方法是使用 read_parquet()write_parquet() 函数。 为了说明这一点,我们将 dplyr 中包含的 starwars 数据写入一个 Parquet 文件,然后将其读回。 首先加载 arrow 和 dplyr 包

library(arrow, warn.conflicts = FALSE)
library(dplyr, warn.conflicts = FALSE)

接下来,我们将数据框写入位于 file_path 的 Parquet 文件

file_path <- tempfile()
write_parquet(starwars, file_path)

Parquet 文件的大小通常比相应的 CSV 文件小得多。 这部分是由于使用了文件压缩:默认情况下,使用 arrow 包编写的 Parquet 文件使用 Snappy 压缩,但也支持其他选项,例如 gzip。 有关更多信息,请参阅 help("write_parquet", package = "arrow")

写入 Parquet 文件后,我们现在可以使用 read_parquet() 读取它

read_parquet(file_path)
## # A tibble: 87 x 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~
## # i 77 more rows
## # i 5 more variables: homeworld <chr>, species <chr>, films <list<character>>,
## #   vehicles <list<character>>, starships <list<character>>

默认设置是返回数据框或 tibble。 如果我们想要一个 Arrow 表,我们将设置 as_data_frame = FALSE

read_parquet(file_path, as_data_frame = FALSE)
## Table
## 87 rows x 14 columns
## $name <string>
## $height <int32>
## $mass <double>
## $hair_color <string>
## $skin_color <string>
## $eye_color <string>
## $birth_year <double>
## $sex <string>
## $gender <string>
## $homeworld <string>
## $species <string>
## $films: list<element <string>>
## $vehicles: list<element <string>>
## $starships: list<element <string>>

Parquet 文件的一个有用特性是它们按列存储数据,并包含元数据,允许文件读取器跳到文件的相关部分。 这意味着可以仅加载列的子集,而无需读取完整的文件。 read_parquet()col_select 参数支持此功能

read_parquet(file_path, col_select = c("name", "height", "mass"))
## # A tibble: 87 x 3
##    name               height  mass
##    <chr>               <int> <dbl>
##  1 Luke Skywalker        172    77
##  2 C-3PO                 167    75
##  3 R2-D2                  96    32
##  4 Darth Vader           202   136
##  5 Leia Organa           150    49
##  6 Owen Lars             178   120
##  7 Beru Whitesun Lars    165    75
##  8 R5-D4                  97    32
##  9 Biggs Darklighter     183    84
## 10 Obi-Wan Kenobi        182    77
## # i 77 more rows

可以使用 props 参数对 Parquet 读取器进行细粒度控制。 有关详细信息,请参阅 help("ParquetArrowReaderProperties", package = "arrow")

将数据写入 Parquet 或 Arrow/Feather 文件以及将这些文件读回 R 时,会保留 R 对象属性。 这支持 sf::sf 对象、带有 haven::labelled 列的 R 数据框以及具有其他自定义属性的数据框的往返写入和读取。 要了解有关如何在 arrow 中处理元数据的更多信息,请参阅元数据文章

Arrow/Feather 格式

开发 Arrow 文件格式是为了提供数据框的二进制列式序列化,使读取和写入数据框更有效率,并使跨数据分析语言共享数据更容易。 此文件格式有时被称为 Feather,因为它是最初的 Feather 项目的延伸,该项目现在已移至 Arrow 项目本身。 您可以在 Arrow 规范页面上找到 Arrow 格式版本 2 的详细规范 – 官方称为Arrow IPC 文件格式

默认情况下,write_feather() 函数写入版本 2 Arrow/Feather 文件,并支持多种文件压缩。 基本用法如下所示

file_path <- tempfile()
write_feather(starwars, file_path)

read_feather() 函数提供了一个熟悉的界面来读取 feather 文件

read_feather(file_path)
## # A tibble: 87 x 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~
## # i 77 more rows
## # i 5 more variables: homeworld <chr>, species <chr>, films <list<character>>,
## #   vehicles <list<character>>, starships <list<character>>

与 Parquet 读取器一样,此读取器支持仅读取列的子集,并可以生成 Arrow 表输出

read_feather(
  file = file_path,
  col_select = c("name", "height", "mass"),
  as_data_frame = FALSE
)
## Table
## 87 rows x 3 columns
## $name <string>
## $height <int32>
## $mass <double>

CSV 格式

arrow 包的读取/写入功能还包括对 CSV 和其他文本分隔文件的支持。 read_csv_arrow()read_tsv_arrow()read_delim_arrow() 函数都使用 Arrow C++ CSV 读取器来读取数据文件,其中 Arrow C++ 选项已映射到参数,映射方式与 readr::read_delim() 中使用的约定相符,并且 col_select 参数的灵感来自 vroom::vroom()

下面显示了一个使用 arrow 写入和读取 CSV 文件的简单示例

file_path <- tempfile()
write_csv_arrow(mtcars, file_path)
read_csv_arrow(file_path, col_select = starts_with("d"))
## # A tibble: 32 x 2
##     disp  drat
##    <dbl> <dbl>
##  1  160   3.9 
##  2  160   3.9 
##  3  108   3.85
##  4  258   3.08
##  5  360   3.15
##  6  225   2.76
##  7  360   3.21
##  8  147.  3.69
##  9  141.  3.92
## 10  168.  3.92
## # i 22 more rows

除了 readr 风格参数 (delimquoteescape_doubleescape_backslash 等) 提供的选项外,您还可以使用 schema 参数来指定列类型:有关详细信息,请参阅 schema() 帮助。 还可以使用 parse_optionsconvert_optionsread_options 来对 arrow csv 读取器进行细粒度控制:有关详细信息,请参阅 help("CsvReadOptions", package = "arrow")

JSON 格式

arrow 包支持从行分隔的 JSON 中读取(但不写入)表格数据,使用 read_json_arrow() 函数。 下面显示了一个最小的示例

file_path <- tempfile()
writeLines('
    { "hello": 3.5, "world": false, "yo": "thing" }
    { "hello": 3.25, "world": null }
    { "hello": 0.0, "world": true, "yo": null }
  ', file_path, useBytes = TRUE)
read_json_arrow(file_path)
## # A tibble: 3 x 3
##   hello world yo   
##   <dbl> <lgl> <chr>
## 1  3.5  FALSE thing
## 2  3.25 NA    NA   
## 3  0    TRUE  NA

延伸阅读