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

How to use the `sink` function within another function in R?

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

中所示

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

您可以为此使用 tryCatch

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

x <-fun()

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

补充上面的答案,warn 选项(参见 ?options)说:

sets the handling of warning messages. If warn is negative all warnings are ignored. If warn is zero (the default) warnings are stored until the top–level function returns. If 10 or fewer warnings were signalled they will be printed otherwise a message saying how many were signalled. An object called last.warning is created and can be printed through the function warnings. If warn is one, warnings are printed as they occur. If warn is two or larger all warnings are turned into errors.

从这个意义上讲,在 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..."