如何为 disk.frame 的 inman st 读数输入一个附加参数?
How can I input a single additional parameter to disk.frame's inmapfn at readin?
根据文章 https://diskframe.com/articles/ingesting-data.html,inmapfn 作为 csv_to_disk_frame(...)
的一部分的一个很好的用例是用于日期转换。在我的数据中,我知道 运行 时间的日期列的名称,并希望将日期输入到一个在读取时间函数中转换。我遇到的一个问题是,除了块本身之外,似乎没有任何其他参数可以传递到 inmapfn 参数中。我无法在 运行 时间使用硬编码变量,因为直到 运行 时间才知道列的名称。
为了澄清这个问题,inmapfn 似乎 运行 在它自己的环境中以防止任何数据 races/other 并行化问题,但我知道变量不会改变所以我希望在那里以某种方式覆盖它,因为我可以确保这是安全的。
我知道我正在调用的函数在任意数据帧上调用时有效。
我在下面提供了一个可重现的示例。
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(do.call(`$`, list(chunk,dates_col)), "%d%b%Y")]
}
)
#> -----------------------------------------------------
#> Stage 1 of 2: splitting the file a.csv into smallers files:
#> Destination: C:\Users\joelk\AppData\Local\Temp\RtmpcFBBkr\file4a1876e87bf5
#> -----------------------------------------------------
#> Stage 1 of 2 took: 0.020s elapsed (0.000s cpu)
#> -----------------------------------------------------
#> Stage 2 of 2: Converting the smaller files into disk.frame
#> -----------------------------------------------------
#> csv_to_disk.frame: Reading multiple input files.
#> Please use `colClasses = ` to set column types to minimize the chance of a failed read
#> =================================================
#>
#> -----------------------------------------------------
#> -- Converting CSVs to disk.frame -- Stage 1 of 2:
#>
#> Converting 5 CSVs to 6 disk.frames each consisting of 6 chunks
#>
#> Error in do.call(`$`, list(chunk, dates_col)): object 'dates_col' not found
您可以尝试使用不同的 backend
和 chunk_reader
参数。例如,如果将 backend
设置为 readr
,则 inmapfn
用户定义的函数将可以访问先前定义的变量。此外,readr
将进行列类型猜测
如果它将字符串格式识别为日期,则会自动估算日期类型列(但是在您的示例数据中,它不会将其识别为日期类型)。
如果您出于性能原因不想使用 readr 后端,那么我会问您的示例是否正确代表了您的实际场景?在您提供的示例中,我没有看到需要将日期列作为变量传递。
您提供的 link 的 Just-in-time transformation 部分中有一个可行的解决方案,我没有发现该示例与您的示例之间有任何额外的复杂性。
如果您确实需要使用默认的 backend
和 chunk_reader
计划并且您 真的 需要向 inmapfn 函数发送一个先前定义的变量,您可以将 csv_to_disk.frame
调用包装在包装函数中:
library(disk.frame)
setup_disk.frame()
df <- tribble(~dates, ~val,
"09feb2021", 2,
"21feb2012", 2,
"09mar2013", 3,
"20apr2021", 4,
)
write.csv(df, file.path(tempdir(), "df.csv"), row.names = FALSE)
wrap_csv_to_disk <- function(col) {
my_date_col <- col
csv_to_disk.frame(
file.path(tempdir(), "df.csv"),
in_chunk_size = 1L,
inmapfn = function(chunk, dates = my_date_col) {
chunk[, dates] <- lubridate::dmy(chunk[[dates]])
chunk
})
}
date_col <- "dates"
df_disk_frame <- wrap_csv_to_disk(date_col)
#> str(collect(df_disk_frame)$dates)
# Date[1:4], format: "2021-02-09" "2012-02-21" "2013-03-09" "2021-04-20"
我明白了。对于解决方法,是否可以做这样的事情?
date_var = knonw_at_runtime()
saveRDS(date_var, "some/path/date_var.rds")
a = csv_to_disk.frame(files, inmapfn = function(chunk) {
date_var = readRDS("some/path/date_var.rds")
# do the rest
})
我认为让 inmapfn
有其他选择是可行的 请参阅 https://github.com/xiaodaigh/disk.frame/issues/377 进行跟踪
根据文章 https://diskframe.com/articles/ingesting-data.html,inmapfn 作为 csv_to_disk_frame(...)
的一部分的一个很好的用例是用于日期转换。在我的数据中,我知道 运行 时间的日期列的名称,并希望将日期输入到一个在读取时间函数中转换。我遇到的一个问题是,除了块本身之外,似乎没有任何其他参数可以传递到 inmapfn 参数中。我无法在 运行 时间使用硬编码变量,因为直到 运行 时间才知道列的名称。
为了澄清这个问题,inmapfn 似乎 运行 在它自己的环境中以防止任何数据 races/other 并行化问题,但我知道变量不会改变所以我希望在那里以某种方式覆盖它,因为我可以确保这是安全的。
我知道我正在调用的函数在任意数据帧上调用时有效。
我在下面提供了一个可重现的示例。
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(do.call(`$`, list(chunk,dates_col)), "%d%b%Y")]
}
)
#> -----------------------------------------------------
#> Stage 1 of 2: splitting the file a.csv into smallers files:
#> Destination: C:\Users\joelk\AppData\Local\Temp\RtmpcFBBkr\file4a1876e87bf5
#> -----------------------------------------------------
#> Stage 1 of 2 took: 0.020s elapsed (0.000s cpu)
#> -----------------------------------------------------
#> Stage 2 of 2: Converting the smaller files into disk.frame
#> -----------------------------------------------------
#> csv_to_disk.frame: Reading multiple input files.
#> Please use `colClasses = ` to set column types to minimize the chance of a failed read
#> =================================================
#>
#> -----------------------------------------------------
#> -- Converting CSVs to disk.frame -- Stage 1 of 2:
#>
#> Converting 5 CSVs to 6 disk.frames each consisting of 6 chunks
#>
#> Error in do.call(`$`, list(chunk, dates_col)): object 'dates_col' not found
您可以尝试使用不同的 backend
和 chunk_reader
参数。例如,如果将 backend
设置为 readr
,则 inmapfn
用户定义的函数将可以访问先前定义的变量。此外,readr
将进行列类型猜测
如果它将字符串格式识别为日期,则会自动估算日期类型列(但是在您的示例数据中,它不会将其识别为日期类型)。
如果您出于性能原因不想使用 readr 后端,那么我会问您的示例是否正确代表了您的实际场景?在您提供的示例中,我没有看到需要将日期列作为变量传递。
您提供的 link 的 Just-in-time transformation 部分中有一个可行的解决方案,我没有发现该示例与您的示例之间有任何额外的复杂性。
如果您确实需要使用默认的 backend
和 chunk_reader
计划并且您 真的 需要向 inmapfn 函数发送一个先前定义的变量,您可以将 csv_to_disk.frame
调用包装在包装函数中:
library(disk.frame)
setup_disk.frame()
df <- tribble(~dates, ~val,
"09feb2021", 2,
"21feb2012", 2,
"09mar2013", 3,
"20apr2021", 4,
)
write.csv(df, file.path(tempdir(), "df.csv"), row.names = FALSE)
wrap_csv_to_disk <- function(col) {
my_date_col <- col
csv_to_disk.frame(
file.path(tempdir(), "df.csv"),
in_chunk_size = 1L,
inmapfn = function(chunk, dates = my_date_col) {
chunk[, dates] <- lubridate::dmy(chunk[[dates]])
chunk
})
}
date_col <- "dates"
df_disk_frame <- wrap_csv_to_disk(date_col)
#> str(collect(df_disk_frame)$dates)
# Date[1:4], format: "2021-02-09" "2012-02-21" "2013-03-09" "2021-04-20"
我明白了。对于解决方法,是否可以做这样的事情?
date_var = knonw_at_runtime()
saveRDS(date_var, "some/path/date_var.rds")
a = csv_to_disk.frame(files, inmapfn = function(chunk) {
date_var = readRDS("some/path/date_var.rds")
# do the rest
})
我认为让 inmapfn
有其他选择是可行的 请参阅 https://github.com/xiaodaigh/disk.frame/issues/377 进行跟踪