【发布时间】:2021-12-27 01:46:29
【问题描述】:
我有一种奇怪的情况,我试图寻找一个特定的警告,如果我看到它就返回一个东西,如果我没有看到它就返回一个不同的东西。我觉得我一定错过了一些东西,但我不知道该怎么做,至少在没有两次调用原始函数的情况下是这样。提前感谢您的任何指点。
具体情况是:我正在读取带有 data.table::fread() 的文件,如果我看到特定的解析警告,我想返回 NULL 而不是(错误地)解析的数据。
以下是我的前三个尝试,以及一些证明它们存在问题的测试。请注意,my_func3 实际上通过了所有测试,但需要读取所有数据两次。显然,在我的实际应用中,数据要大得多,因此这绝对是不理想的。
# this one fails test 3
# because it doesn't return anything if _any_ warning is caught
my_func1 <- function(.string) {
res <- tryCatch(
{
data.table::fread(text = .string)
},
warning = function(.w) {
if (grepl("Stopped early.+TABLE NO", .w$message)) {
warning("my custom warning")
return(NULL)
} else {
warning(.w)
}
}
)
}
# this one fails test 2
# because it returns the parsed df even if we catch the custom warning
my_func2 <- function(.string) {
res <- withCallingHandlers(
{
data.table::fread(text = .string)
},
warning = function(.w) {
if (grepl("Stopped early.+TABLE NO", .w$message)) {
warning("my custom warning")
return(NULL)
} else {
warning(.w)
}
}
)
}
# this one passes all three
# but it requires reading the data twice
my_func3 <- function(.string) {
res <- tryCatch(
{
data.table::fread(text = .string)
},
warning = function(.w) {
if (grepl("Stopped early.+TABLE NO", .w$message)) {
warning("my custom warning")
return(NULL)
} else {
data.table::fread(text = .string)
}
}
)
}
##################
# TESTS
##################
# uncomment the one you want to test
#my_func <- my_func1
#my_func <- my_func2
#my_func <- my_func3
library(testthat)
test_that("test 1: my_func returns df when no warning", {
df <- my_func("a,b\n1,2\n3,4")
expect_equal(nrow(df), 2)
expect_equal(ncol(df), 2)
})
test_that("test 2: my_func warns and returns NULL on custom warning", {
expect_warning(
df <- my_func("a,b\n1,2\nTABLE NO\n3,4"),
regexp = "my custom warning"
)
expect_null(df)
})
test_that("test 3: my_func warns and returns df on other warning ", {
expect_warning(
df <- my_func("a,b\n1,2,3\n")
)
expect_equal(nrow(df), 1)
expect_equal(ncol(df), 3)
})
非常感谢您对如何读取数据两次来完成此操作的任何想法。
【问题讨论】:
标签: r error-handling