Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top