gpt4 book ai didi

r - warning.expression 阻止更新 last.warning

转载 作者:行者123 更新时间:2023-12-02 13:48:36 30 4
gpt4 key购买 nike

我有兴趣尝试在调用时操纵警告,而无需围绕方法创建支持基础设施。也就是说,我需要能够捕获警告,而无需使用以下代码包装代码:

tryCatch(..., warning = function() { action() } )

我相信我可以使用warning.expression来做到这一点处理程序。

但是,我遇到的问题是 last.warningwarning.expression 的警告调度期间调用时未能检索到最新警告。

例如:

warning_handler = function() {
if (exists("last.warning", baseenv()) &&
!is.null(last.warning)) {
warning_contents = names(last.warning)
} else {
warning_contents = NA
}

message(warning_contents)
}


options(warning.expression = quote({ warning_handler() }))

warning("test1")
# test1
warning("testing2")
# test1
warning("sampletest3")
# test1

如果我恢复使用默认处理程序,例如NULL,则消息会以无法与其交互为代价进行更新。

options(warning.expression = NULL)

warning("test1")
# Warning message:
# test1
warning("testing2")
# Warning message:
# testing2
warning("sampletest3")
# Warning message:
# sampletest3

我是否缺少与处理程序相关的内容?

最佳答案

添加 warning.expression 几乎肯定会干扰警告收集机制。我对此不是 100% 确定,但如果你看一下(R.3.4.0,我有一份旧的源代码副本),你可以在 error.c@335 中看到:

static void vwarningcall_dflt(SEXP call, const char *format, va_list ap)
{
int w;
SEXP names, s;
const char *dcall;
char buf[BUFSIZE];
RCNTXT *cptr;
RCNTXT cntxt;

if (inWarning)
return;

s = GetOption1(install("warning.expression"));
if( s != R_NilValue ) {
if( !isLanguage(s) && ! isExpression(s) )
error(_("invalid option \"warning.expression\""));
cptr = R_GlobalContext;
while ( !(cptr->callflag & CTXT_FUNCTION) && cptr->callflag )
cptr = cptr->nextcontext;
eval(s, cptr->cloenv);
return;
}
// ... snip ...


else if(w == 0) { /* collect them */
if(!R_CollectWarnings) setupwarnings();
if(R_CollectWarnings < R_nwarnings) {
SET_VECTOR_ELT(R_Warnings, R_CollectWarnings, call);
Rvsnprintf(buf, min(BUFSIZE, R_WarnLength+1), format, ap);
// ... snip ...
}

因此return之后的部分不会运行。

看起来last.value是由errors.c@466中的printWarnings填充的,所以这要么发生在warning.expressions之后> 处理程序,或更可能根本不处理:

attribute_hidden
void PrintWarnings(void)
{
// ... snip to very end of fun ...

/* now truncate and install last.warning */
PROTECT(s = allocVector(VECSXP, R_CollectWarnings));
PROTECT(t = allocVector(STRSXP, R_CollectWarnings));
names = CAR(ATTRIB(R_Warnings));
for(i = 0; i < R_CollectWarnings; i++) {
SET_VECTOR_ELT(s, i, VECTOR_ELT(R_Warnings, i));
SET_STRING_ELT(t, i, STRING_ELT(names, i));
}
setAttrib(s, R_NamesSymbol, t);
SET_SYMVALUE(install("last.warning"), s);
UNPROTECT(2);

endcontext(&cntxt);

inPrintWarnings = 0;
R_CollectWarnings = 0;
R_Warnings = R_NilValue;
return;
}

所以很可能就是这样。我还没有研究过流程模式,所以我可能是错的。如果我是对的,似乎没有办法从 warning.expression 获取警告信息。

除此之外,请注意 last.warning 被记录为未记录,FWIW。

关于r - warning.expression 阻止更新 last.warning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48071718/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com