Вопрос

How can warning messages be saved in a vector or data frame within a loop so that they can be associated with a specific iteration?

Here's a toy example where I would like to store results and warning message (if any) from an operation (log(k)) in a data frame alongside the data (k):

dat <- data.frame(k=c(3,5,-2,7), logk=NA, warnMsg=NA)
for(i in 1:nrow(dat)){
  w <- length(warnings())
  dat$logk[i] <- log(dat$k[i])
  #if new warning, assign to data frame
  if(length(warnings()) > length (w)){
     dat$warnMsg[i] <- warnings()[length(warnings())]
  }
}

It seems this doesn't work because any warnings that are generated within the loop are not available to the warnings() call until the loop is over. Do I need to specify a different environment to access new warnings within the loop?

I suspect there is also a better way to do this altogether using try() or tryCatch() but it isn't obvious to me yet.

Это было полезно?

Решение

You can accomplish what you want with the withCallingHandlers function, like so

withCallingHandlers({
    for(i in 1:nrow(dat)){
        w <- length(warnings())
        dat$logk[i] <- log(dat$k[i])
    }
}, warning = function(w){
    dat$warnMsg[i] <<- w$message
    invokeRestart("muffleWarning")
})

Notice that you need the <<- operator in the warning handler to assign the message to the data frame in the global environment, since <- would create a local copy of dat within the handler and discard it upon exit.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top