2

我正在使用包中的某些功能fitdistrplus作为我正在创建的包的一部分。

我试图防止在运行函数时在控制台中显示任何错误消息,而是希望将错误消息记录在我正在创建的错误日志中。

在大多数情况下,使用tryCatch()使我能够做到这一点。

但特别是对于该fitdist()函数,即使正在将消息写入错误日志(意味着tryCatch()表达式正在运行),我也无法抑制在控制台中打印的错误消息。

我在下面的代码中复制了我的问题。

library(fitdistrplus)

file.create("error_log.txt")

func_desc<-function(x){
  tryCatch({
    descdist(data = x)
  },error = function(e){
    write(x = paste(Sys.time(),"Error in func_desc :",e$message,sep = " "),file = "error_log.txt",append = T,sep = "\n")
  })
}

func_fit<-function(x,dist){
  tryCatch({
    fitdist(data = x,distr = dist)
  },error = function(e){
    write(x = paste(Sys.time(),"Error in func_fit :",e$message,sep = " "),file = "error_log.txt",append = T,sep = "\n")
  })
}

# Creating a vector of repeated values which will result in an error
test<-rep(x = 1,times = 10)

func_desc(x = test)
# Results in an error and the message is written to the error log and not printed in the console

func_fit(x = test,dist = "beta")
# Results in an error and the message is both written to the error log and printed in the console

我想禁止打印此错误消息func_fit()

我已经尝试过以下替代方案:

  1. try()silent = TRUE. 仍然会打印错误消息。
  2. conditionMessage()给出相同的结果。
  3. withCallingHandlers()在某些帖子和线程中已提出建议,但我不确定如何正确实施。
  4. 与函数一起使用invisible()仍然会打印错误。
4

1 回答 1

3

这是因为fitdist(或者实际上,mledist由 调用fitdist)已经在进行一些错误捕获。原来的错误在optim并且已经被捕获,然后将错误信息mledist 打印到控制台。所以你看到的并不是真正的错误甚至警告,它是一个打印语句,其中包含捕获的错误消息的内容。

这样做的一点mledist是:

    if (inherits(opttryerror, "try-error")) {
        warnings("The function optim encountered an error and stopped.")
        if (getOption("show.error.messages")) 
            print(attr(opttryerror, "condition"))
        return(list(estimate = rep(NA, length(vstart)), convergence = 100, 
            loglik = NA, hessian = NA, optim.function = opt.fun, 
            fix.arg = fix.arg, optim.method = meth, fix.arg.fun = fix.arg.fun, 
            counts = c(NA, NA)))
    }

这不是一个很好的做法,正是因为它会导致您现在遇到的问题;它阻止其他人系统地处理错误。

show.error.messages正如您从该代码中看到的那样,您可以通过将选项设置为 FALSE 来关闭它:

options(show.error.messages = FALSE)

但是您要小心这一点,因为在 R 会话的其余部分您不会看到任何错误消息。你绝对不想对别人的会话这样做。

另一种选择是使用sink("extra-error-messages.txt")将所有打印发送到某个地方的控制台(甚至可能发送给您error_log.txt,但我不确定这是否会导致写入多个内容的问题)。

于 2018-07-03T05:41:59.793 回答