R中结合arrow包与dplyr求和时随机出现NA的技术问询
R中arrow + dplyr分组求和随机返回NA的问题排查与解决
问题描述
使用arrow包读取Parquet数据集,结合dplyr执行分组求和操作时,sum(vl_frete)会随机返回NA,但通过count()验证可知,fluxo="imp"分组中不存在vl_frete为NA的记录。
复现代码
library(arrow) library(dplyr) td <- tempdir() tzip <- file.path(td, "reprex.zip") download.file("https://drive.google.com/uc?export=download&id=1-KefpiALDtUg0PrCUgpMAaE0903jVWWm", destfile = tzip) unzip(tzip, exdir = td) tlink <- file.path(td, "co_ano_mes=1997-01-01") arrow_dset <- arrow::open_dataset( tlink, format = "parquet" ) # 验证imp分组无NA arrow_dset%>% count(fluxo, vl_frete_miss=is.na(vl_frete)) %>% collect()
验证结果
fluxo vl_frete_miss n <chr> <lgl> <int> exp TRUE 35546 imp FALSE 42332
重复求和的异常结果
replicate(10, arrow_dset %>% group_by(fluxo) %>% summarise(vl_frete = sum(vl_frete)) %>% collect %>% filter(fluxo=="imp") %>% pull(vl_frete))
执行结果:
[1] NA NA 154149785 NA 154149785 NA 154149785 154149785 [9] 154149785 154149785
可能原因
这类随机NA通常是arrow底层的并行处理或分片读取bug导致:
- 旧版本arrow在Parquet数据集的分片聚合计算中存在稳定性问题;
- 多线程处理时,部分分片的求和逻辑出现异常,最终汇总返回NA。
解决方案
1. 更新arrow到最新稳定版
旧版本的bug通常会在新版本中修复,执行以下命令更新:
install.packages("arrow")
2. 禁用并行处理
在open_dataset中关闭多线程,强制单线程执行计算,避免并行带来的异常:
arrow_dset <- arrow::open_dataset( tlink, format = "parquet", use_threads = FALSE )
3. 先加载数据到内存再计算
如果数据集大小允许,先将数据完整加载到内存(collect()),再执行dplyr操作,绕开arrow的分片处理逻辑:
arrow_dset %>% collect() %>% group_by(fluxo) %>% summarise(vl_frete = sum(vl_frete)) %>% filter(fluxo=="imp") %>% pull(vl_frete)
4. 显式设置na.rm=TRUE
即使原始数据无NA,显式指定忽略NA的参数,可强制arrow忽略计算过程中可能出现的临时异常值:
arrow_dset %>% group_by(fluxo) %>% summarise(vl_frete = sum(vl_frete, na.rm = TRUE)) %>% collect %>% filter(fluxo=="imp") %>% pull(vl_frete)
内容的提问来源于stack exchange,提问作者Eduardo Leoni
相关产品推荐
相关产品推荐

