library(tibble)
patch_tibble()
df <- tibble(gender=c(1,1,0))
df$male
Error in `df$male`:
! Unknown or uninitialised column: `male`.
Run `rlang::last_trace()` to see where the error occurred.
function (x, name)
{
out <- .subset2(x, name)
if (is.null(out)) {
warn(paste0("Unknown or uninitialised column: ", tick(name),
"."))
}
out
}
stop您可以简单地使用或将警告替换为错误rlang:abort():
`$.tbl_df` <- function (x, name) {
out <- .subset2(x, name)
if (is.null(out)) {
rlang::abort(paste0("Unknown or uninitialised column: ", name, "."))
}
out
}
然后,正如预期的那样:
> df$male
Error in `$.tbl_df`(df, male) : Unknown or uninitialised column: male.
patch_tibble <- function(){
# The modified "$.tbl_df" function
f <- function (x, name) {
out <- .subset2(x, name)
if (is.null(out)) {
abort(paste0("Unknown or uninitialised column: ", tick(name),
"."))
}
out
}
# Set the function's namespace to tibble
environment(f) <- asNamespace("tibble")
# Replace the original function with our modified version
utils::assignInNamespace("$.tbl_df", f, "tibble")
print("Patched tibble!")
}
输出结果如下:
> patch_tibble()
[1] "Patched tibble!"
> df$male
Error in `df$male`:
! Unknown or uninitialised column: `male`.
这有点儿不靠谱,但你可以修补该函数,即 getter。当在 中找不到列名时,
$
会抛出警告。通过用 替换此调用,我们可以将此警告转换为错误。rlang::warn
df
rlang::abort
S3 方法的原始函数
$.tbl_df
定义如下:stop
您可以简单地使用或将警告替换为错误rlang:abort()
:然后,正如预期的那样:
附录
正如评论中指出的那样,如果
$.tbl_df
在内部调用此解决方案,则可能会导致问题。按照@Billy34的提示,我们可以$.tbl_df
用修改后的函数替换内部函数,如下所示:输出结果如下:
根据@BenBolker 的回答中的想法,您可以创建一个全局处理程序:
当然,如果警告被分类的话这会更简单。
这可能是您能得到的最接近的答案(没有像上一个答案那样进行黑客攻击):使用
tryCatch()
检查警告消息(如果有人使用已翻译警告的不同语言设置,此操作将会失败)。其他人已经给出了解决此问题的方法。在此回答中,我将解释
tibble
作者可以采取哪些措施来简化此工作。R 支持分类错误和警告,但它们并不常用。
rlang
包中对class
、 和 都有参数abort()
。warn()
您inform()
不需要使用rlang
,所有操作都可以用基本函数完成,但它们很好地打包了它。因此,
tibble
可以做的是,为他们发出的每个警告设置一个单独的类。然后,您可以捕获与您感兴趣的警告相对应的特定类,并将其转换为错误。或者,您可以创建自己的$.tbl_df
方法来执行此操作,然后选择是否要进行转换。例如,
他们本可以写
然后你可以运行
捕获该警告,并将其转换为错误。我将其转换为带类的错误,
"error.$.tbl_df"
以便其他代码可以捕获该错误,但没有必要这样做。我还设置了,call = NULL
这样您就不会被告知代码中的一行$.tbl_df
对您毫无意义。如果您尝试设置,您也许能够找到df$male
表达式;我不确定它会回溯到多远。