如何向disk.frame的inmapfn参数传入读取阶段的额外自定义参数
问题原因
csv_to_disk.frame的inmapfn会在独立的worker进程环境中执行,默认不会携带主进程中定义的全局变量,因此你的代码中worker无法识别dates_col变量,才会抛出找不到对象的错误。
解决方案1:使用globals参数显式传入变量
disk.frame框架支持通过globals参数声明需要同步到worker环境的变量,只要你保证这些变量在运行过程中不会修改,该方式是完全安全的,也是官方推荐的跨worker传参方案。
同时你原来的列调用写法可以简化为[[索引,不需要用do.call调用$,可读性更高。
修改后的可运行代码如下:
library(tidyverse) library(disk.frame) setup_disk.frame() a <- tribble(~dates, ~val, "09feb2021", 2, "21feb2012", 2, "09mar2013", 3, "20apr2021", 4, ) write_csv(a, "a.csv") dates_col <- "dates" tmp.df <- csv_to_disk.frame( "a.csv", outdir = file.path(tempdir(), "tmp.df"), in_chunk_size = 1L, inmapfn = function(chunk) { chunk[, sdate := as.Date(chunk[[dates_col]], "%d%b%Y")] }, # 显式声明要传入worker的变量 globals = c("dates_col") ) # 验证转换结果 head(tmp.df)
解决方案2:用闭包绑定变量
如果你不想依赖globals参数,也可以通过函数工厂生成inmapfn,提前把动态的列名绑定到函数的执行环境中:
# 定义生成inmapfn的函数工厂 generate_inmapfn <- function(target_col) { function(chunk) { chunk[, sdate := as.Date(chunk[[target_col]], "%d%b%Y")] } } # 生成绑定了当前dates_col的inmapfn custom_inmapfn <- generate_inmapfn(dates_col) # 调用时不需要额外传globals tmp.df <- csv_to_disk.frame( "a.csv", outdir = file.path(tempdir(), "tmp.df"), in_chunk_size = 1L, inmapfn = custom_inmapfn )
两种方案都可以实现动态列名的日期转换需求,运行后不会再出现变量找不到的报错。
内容的提问来源于stack exchange,提问作者Joel Kandiah
相关产品推荐
相关产品推荐

