balin
balin

Reputation: 1686

R - `try` in conjunction with capturing ALL console output?

Here's a piece of code I'm working with:

install.package('BiocManager');BiocManager::install('UniProt.ws')
requireNamespace('UniProt.ws')
uniprot_object <- UniProt.ws::UniProt.ws(
  UniProt.ws::availableUniprotSpecies(
    pattern = '^Homo sapiens$')$`taxon ID`)
query_results <- try(
    UniProt.ws::select(
      x = uniprot_object,
      keys = 'BAA08084.1',
      keytype = 'EMBL/GENBANK/DDBJ',
      columns = c('ENSEMBL','UNIPROTKB')))

This particular key/keytype combination is non-productive and produces the following output:

Getting mapping data for BAA08084.1 ... and ACC
error while trying to retrieve data in chunk 1:
  no lines available in input
continuing to try
Error in `colnames<-`(`*tmp*`, value = `*vtmp*`) : 
  attempt to set 'colnames' on an object with less than two dimensions

Of the two [eE]rrors reported only the second is a 'proper' R error object and given the use of try accordingly captured in the variable query_result.

I am, however, desperate to capture the other error bit (no lines available in input) to inform downstream programmatic processes.

After playing with a plethora of capture.output, sink, purrr::quietly, etc. options found by startpaging (googling), I continue to fail capturing that bit. How can I do that?

Upvotes: 1

Views: 246

Answers (2)

balin
balin

Reputation: 1686

Based on @user2554330 s most excellent answer, I constructed an ugly thing that does exactly what I want:

  1. try to execute the statement
  2. don't fail fatally
  3. leave no ugly messages
  4. allow me access to errors and messages

So here it is in all it's despicable glory:

  saveMessages <- c()
  query_results <- suppressMessages(
    withCallingHandlers(
      try(
        UniProt.ws::select(
          x = uniprot_object,
          keys = 'BAA08084.1',
          keytype = 'EMBL/GENBANK/DDBJ',
          columns = c('ENSEMBL','UNIPROTKB')),
        silent = TRUE),
      message = function(e)
        saveMessages <<- c(saveMessages, conditionMessage(e))))

Upvotes: 0

user2554330
user2554330

Reputation: 44808

As @Csd suggested, you could use tryCatch. The message that you are after is printed by the message() function in R, not stop(), so try() will ignore it. To capture output from message(), use code like this:

query_results <- tryCatch(
   UniProt.ws::select(
     x = uniprot_object,
     keys = 'BAA08084.1',
     keytype = 'EMBL/GENBANK/DDBJ',
     columns = c('ENSEMBL','UNIPROTKB')), 
   message = function(e) conditionMessage(e))

This will abort evaluation when it gets any message, and return the message in query_results. If you are doing more than debugging, you probably want the message saved, but evaluation to continue. In that case, use withCallingHandlers instead. For example,

saveMessages <- c()
query_results <- withCallingHandlers(
   UniProt.ws::select(
     x = uniprot_object,
     keys = 'BAA08084.1',
     keytype = 'EMBL/GENBANK/DDBJ',
     columns = c('ENSEMBL','UNIPROTKB')), 
   message = function(e) 
               saveMessages <<- c(saveMessages, conditionMessage(e)))

When I run this version, query_results is unchanged (because the later error aborted execution), but the messages are saved:

saveMessages
[1] "Getting mapping data for BAA08084.1 ... and ACC\n"                                                    
[2] "error while trying to retrieve data in chunk 1:\n    no lines available in input\ncontinuing to try\n"

Upvotes: 3

Related Questions