使用“…”有问题’有关系



这是昨天问的将消息转换为字符向量的后续问题。我正在开发一个函数,从函数调用返回输出消息(如果有的话)作为字符向量。我想把它概括一下,在下面的函数中,FUN是一个函数,argarg1是第一个参数,...是进一步的参数。第一个函数运行良好。

getMessage <- function(FUN, arg)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    eval(call(FUN, arg))
    sink(NULL, type = "message")
    messages
}
getMessage(scan, "data.txt")
# [1] "Read 15 items"

但是当我添加...时,为了能够将其推广到其他函数调用,我没有得到输出,"messages"连接保持打开。

getMessage <- function(FUN, arg1, ...)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    eval(call(FUN, arg1, ...))
    sink(NULL, type = "message")
    messages
}
> getMessage(scan, "data.txt")
> showConnections()
#   description class            mode text   isopen   can read can write
# 3 "messages"  "textConnection" "w"  "text" "opened" "no"     "yes"   

...还能在函数中使用吗?sink有进一步的论点,我可能希望在某些时候使用。

编辑

文件"data.txt"可以用以下代码创建

> m <- matrix(c(13, 14, 4950, 20, 50, 4949, 22, 98, 4948, 30, 58, 4947, 43, 48, 4946),
              5, byrow = TRUE)
> write.table(m, "data.txt", row.names = F, col.names = F)

call失败,因为您不能在此函数中以这种方式使用...。如果您关闭水槽,您将看到错误消息。您将需要用tryCatch封装对eval的调用并打印错误,如果遇到错误,则使用do.call而不是eval + call

getMessage <- function(FUN, ...)
{
    FUN <- deparse(substitute(FUN))
    tc <- textConnection("messages", "w")
    on.exit(close(tc))
    sink(tc, type = "message")
    tryCatch(do.call(FUN, list(...)), error=function(e) {message(e$message)})
    sink(NULL, type = "message")
    messages
}
getMessage(scan, "data.txt")

最新更新