Подавить сообщение об ошибке при использовании fitdist () из пакета fitdistrplus - PullRequest
0 голосов
/ 02 июля 2018

Я использую определенные функции из пакета 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() с функциями по-прежнему выдает ошибку.

1 Ответ

0 голосов
/ 03 июля 2018

Это происходит потому, что 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, но я не уверен, что это вызовет проблемы с несколькими вещами, записывающими в него).

...