使用apache箭头读取一个R数据帧中的分区镶木地板目录(所有文件)

时间:2019-10-17 20:02:49

标签: r rstudio parquet apache-arrow

如何将带箭头的分区实木复合地板文件读取到R中(没有任何火花)

情况

  1. 使用Spark管道创建镶木地板文件并保存在S3上
  2. 使用RStudio / RShiny读取,以一列为索引进行进一步分析

实木复合地板文件结构

从我的Spark创建的实木复合地板文件由几部分组成

tree component_mapping.parquet/
component_mapping.parquet/
├── _SUCCESS
├── part-00000-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
├── part-00001-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
├── part-00002-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
├── part-00003-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
├── part-00004-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet
├── etc

如何将这个component_mapping.parquet读入R?

我尝试过的事情

install.packages("arrow")
library(arrow)
my_df<-read_parquet("component_mapping.parquet")

但这失败并显示错误

IOError: Cannot open for reading: path 'component_mapping.parquet' is a directory

如果我只读取目录的一个文件,它将起作用

install.packages("arrow")
library(arrow)
my_df<-read_parquet("component_mapping.parquet/part-00000-e30f9734-71b8-4367-99c4-65096143cc17-c000.snappy.parquet")

但是我需要全部加载才能查询

我在文档中找到的内容

在Apache箭头文档中 https://arrow.apache.org/docs/r/reference/read_parquet.htmlhttps://arrow.apache.org/docs/r/reference/ParquetReaderProperties.html 我发现这里有一些read_parquet()命令的属性,但是我无法正常运行,也找不到任何示例。

read_parquet(file, col_select = NULL, as_data_frame = TRUE, props = ParquetReaderProperties$create(), ...)

如何正确设置属性以读取完整目录?

# should be this methods
$read_dictionary(column_index)
or
$set_read_dictionary(column_index, read_dict)

我们将不胜感激

4 个答案:

答案 0 :(得分:2)

通过(单个)文件阅读器设置选项无法读取文件目录。如果没有问题,那么今天您可以在目录列表中search_provider / lapply,然后map / rbind进入单个data.frame。可能有一个bind_rows函数可以很清楚地做到这一点。在文件的迭代过程中,如果只需要数据的已知子集,则还可以对每个文件进行选择/过滤。

在Arrow项目中,我们正在积极开发多文件数据集API,该API可让您执行您想做的事情,并将行和列的选择下推到单个文件等等。敬请期待。

答案 1 :(得分:1)

解决方案:用箭头将分区的实木复合地板文件从本地文件系统读取到R数据框中

由于我想避免在RShiny服务器上使用任何Spark或Python,所以不能使用其他库,例如sparklyrSparkRreticulatedplyr如描述的在How do I read a Parquet in R and convert it to an R DataFrame?

我现在通过arrowlapplyrbindlist的提案来解决您的提案

my_df <-data.table::rbindlist(lapply(Sys.glob("component_mapping.parquet/part-*.parquet"), arrow::read_parquet))

向前看,直到可以使用apache箭头功能 谢谢

答案 2 :(得分:1)

正如@neal-richardson 在他的回答中提到的,在这方面已经做了更多的工作,并且使用当前的 arrow(我目前运行的是 4.0.0)有可能。

我注意到您的文件使用了 snappy 压缩,这在安装前需要一个特殊的构建标志。 (此处的安装文档:https://arrow.apache.org/docs/r/articles/install.html

Sys.setenv("ARROW_WITH_SNAPPY" = "ON")
install.packages("arrow",force = TRUE)

Dataset API 使用多文件数据集实现您正在寻找的功能。虽然文档还没有包含各种各样的示例,但它确实提供了一个明确的起点。 https://arrow.apache.org/docs/r/reference/Dataset.html

下面的示例显示了从给定目录读取多文件数据集并将其转换为内存中的 R 数据帧的最小示例。 API 还支持过滤条件和选择列的子集,但我仍在尝试自己弄清楚语法。

library(arrow)

## Define the dataset
DS <- arrow::open_dataset(sources = "/path/to/directory")
## Create a scanner
SO <- Scanner$create(DS)
## Load it as n Arrow Table in memory
AT <- SO$ToTable()
## Convert it to an R data frame
DF <- as.data.frame(AT)

答案 3 :(得分:0)

解决方案:使用箭头将S3中的分区镶木文件读取到R数据框中

由于我现在花了很长时间才能找到解决方案,而我无法在网络上找到任何东西,因此我想与我分享这个解决方案,以了解如何从S3中读取分区的镶木地板文件

library(arrow)
library(aws.s3)

bucket="mybucket"
prefix="my_prefix"

# using aws.s3 library to get all "part-" files (Key) for one parquet folder from a bucket for a given prefix pattern for a given component
files<-rbindlist(get_bucket(bucket = bucket,prefix=prefix))$Key

# apply the aws.s3::s3read_using function to each file using the arrow::read_parquet function to decode the parquet format
data <- lapply(files, function(x) {s3read_using(FUN = arrow::read_parquet, object = x, bucket = bucket)})

# concatenate all data together into one data.frame
data <- do.call(rbind, data)

What a mess but it works.
@neal-richardson is there a using arrow directly to read from S3? I couldn't find something in the documentation for R