【问题标题】:How to use the `sink` function within another function in R?如何在 R 中的另一个函数中使用“sink”函数?
【发布时间】:2019-08-26 12:25:41
【问题描述】:

我有一个函数fun,它依赖于一个外部函数external(即,来自某个包)。如何在字符向量中收集来自external 的所有警告?

这是一个最小设置:

# External function from another package.
external <- function() {
    warning("warning from external...")
}


# Function meant to capture the warnings.
fun <- function() {
    # Create variable to store the warnings.
    warns <- vector("character")

    # Create connection for the sink.
    connection <- textConnection("warns", "wr", local = TRUE)

    # Start collecting.
    sink(connection, type = "message")

    # Call external function and produce a warning.
    external()

    # Reset the sink.
    sink(type = "message")

    # Close the connection.
    close(connection)

    return(warns)
}

然而,输出看起来像这样:

x <- fun()
# Warning message:
# In external() : warning from external...

print(x)
# character(0)

我对@9​​87654328@ 不感兴趣,而是记录这些警告。当我在函数之外使用sink 时,它似乎可以工作,正如this answer 中所示。

【问题讨论】:

  • 你知道warnings 已经登录了吗?
  • 你的意思是在R创建的last.warning中?
  • 是的,但您可能还想查看选项 warning.expression 以覆盖警告行为 - 即记录而不是打印。
  • @James,你能扩展一点吗?我觉得这个方法很有意思!
  • 不幸的是,这可能是不可能的,这里有一个讨论:stackoverflow.com/questions/48071718/…

标签: r sink


【解决方案1】:

您可以为此使用tryCatch

fun <- function() {
  tryCatch(external(), warning = function(my_warn) my_warn$message)
}

x <-fun()

x
# [1] "warning from external..."

【讨论】:

  • 我完全没有注意到 tryCatchwarning 参数。不错!
  • 您能否看一下受您的回答启发的this question?谢谢!
【解决方案2】:

如果您想将警告存储在字符向量中,可以尝试 evaluate 包中的 evaluate() 函数:

external <- function() {
  warning("warning from external...")
}

# Function meant to capture the warnings.
fun <- function() {
   #some operation
   x=1+2;
   warnings_ls = evaluate::evaluate(external())
   return(list(value=x,warn=warnings_ls))
}

x <- fun()

> a$warn[[1]]$src
[1] "warning from external..."

> a$value
[1] 3

【讨论】:

  • 谢谢,了解evaluate 包很有用!
【解决方案3】:

作为上述答案的补充,warn 选项(参见?options)表示:

设置警告消息的处理。如果warn 为负数,则忽略所有警告。 如果warn 为零(默认值),则将存储警告,直到顶级函数返回。 如果发出了 10 个或更少的警告,则将打印它们,否则将显示一条消息,说明发出了多少个警告。一个名为last.warning 的对象被创建并且可以通过函数warnings 打印。 如果 warn 为 1,则在出现警告时打印警告。 如果 warn 为 2 或更大,则所有警告都将转换为错误。

从这个意义上说,在sink 之前设置options(warn = 1) 可以捕获警告消息。重置sink(即options(warn = 0))后,warn 可以恢复为默认值。然后,fun 看起来像:

fun <- function() {
    # Print warnings as they occur.
    options(warn = 1)

    # Create variable to store the warnings.
    warns <- vector("character")

    # Create connection for the sink.
    connection <- textConnection("warns", "wr", local = TRUE)

    # Start collecting.
    sink(connection, type = "message")

    # Call external function and produce a warning.
    external()

    # Reset the sink.
    sink(type = "message")

    # Close the connection.
    close(connection)

    # Restore default warning behavior.
    options(warn = 0)

    return(warns)
}

输出如下:

fun()
# [1] "Warning in external() : warning from external..."

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多