如何在R中的另一个函数中使用`sink`函数?

时间:2019-08-26 12:25:41

标签: r sink

我有一个函数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)

我对suppressWarnings不感兴趣,而是记录了这些警告。当我在函数外使用sink时,它似乎可以正常工作,就像this answer所示。

3 个答案:

答案 0 :(得分:2)

您可以使用tryCatch

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

x <-fun()

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

答案 1 :(得分:1)

如果要将警告存储在字符向量中,可以尝试使用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

答案 2 :(得分:1)

作为上述答案的补充,warn选项(请参阅?options)说:

  

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

从这种意义上说,在options(warn = 1)之前设置sink可以捕获警告消息。重置warn(即sink)后,可以将options(warn = 0)恢复为默认值。然后,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..."