R 中箭头数据集过滤表达式的正确语法

Mat*_*ill 7 r apache-arrow

我正在尝试使用arrow(最近实现的) DataSet API 将文件目录读入内存,并利用c++后端来过滤行和列。我想arrow直接使用包函数,而不是样式动词的包装函数dplyr。截至目前,这些函数还处于其生命周期的早期阶段,因此我很难找到一些说明语法的示例。

为了理解语法,我创建了一个非常小的测试示例。前两个查询按预期工作。

library(arrow) ## version 4.0.0

write.csv(mtcars,"ArrowTest_mtcars/mtcars.csv")
## Define a dataset object
DS <- arrow::open_dataset(sources = "ArrowTest_mtcars", format = "text")

## Generate a basic scanner 
AT <- DS$NewScan()$UseThreads()$Finish()$ToTable()
head(as.data.frame(AT), n = 3)
##                      mpg cyl disp  hp drat    wt  qsec vs am gear carb
## 1         Mazda RX4 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## 2     Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## 3        Datsun 710 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1

## Generate a basic scanner with projection to select columns
AT <- DS$NewScan()$UseThreads()$Project(c("mpg","cyl"))$Finish()$ToTable()
head(as.data.frame(AT), n = 3)    
#   mpg cyl
#1 21.0   6
#2 21.0   6
#3 22.8   4
Run Code Online (Sandbox Code Playgroud)

但是,我还无法找出实现过滤表达式的正确语法。我已经尝试了很多方法,但我最好的猜测仍然不起作用,并且在执行该行时导致段错误Filt <- Expression$create(...)

## Generate a basic scanner with filtering where column `cyl` = 6    
## My best guess at what might work, but causes a segfault instead
Filt <- Expression$create("==",args = list(Expression$field_ref("cyl"), Scalar$create(6L)))

AT <- DS$NewScan()$UseThreads()$Filter(Filt)$Finish()$ToTable()
head(as.data.frame(AT))
Run Code Online (Sandbox Code Playgroud)

实现基于行的过滤的正确语法是什么?

Oli*_*ver 6

文档对此非常糟糕。但一些尝试和测试实际上让我得到了一些可能会引导你找到正确答案的东西。我发现的问题是Scalar$create 知道要使用哪个函数:

Filt = Expression$create('or', 
                         args = list(Expression$field_ref("cyl") == 6L, 
                                     Expression$field_ref('cyl') == 4L))

AT <- DS$NewScan()$UseThreads()$Filter(Filt)$Finish()$ToTable()
head(as.data.frame(AT))
Run Code Online (Sandbox Code Playgroud)

但是,请注意,对于单个条件,只需Expression$field_ref(...) == x直接在过滤器中使用即可

AT <- DS$NewScan()$UseThreads()$Filter(Expression$field_ref("cyl") == 6L)$Finish()$ToTable()
head(as.data.frame(AT))
Run Code Online (Sandbox Code Playgroud)

  • 我无法评价“dplyr”的总体稳定性,但在这种特殊情况下,如果您正在寻找 API 稳定性,我建议使用带箭头的 dplyr。`dplyr::filter()` 绝对稳定,比 Arrow 的低级 API 稳定得多。当我们添加功能时,我们会测试您在查询 Arrow Table 时获得的输出是否与使用“dplyr”查询 data.frame 时获得的输出相同——因此,我们最强有力的 API 保证是使用“dplyr”时,一切都会按照您的预期工作。 (3认同)