【问题标题】:R - `try` in conjunction with capturing ALL console output?R - `try`结合捕获所有控制台输出?
【发布时间】:2018-11-16 15:27:12
【问题描述】:

这是我正在使用的一段代码:

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')))

这个特定的键/键类型组合是非生产性的,并产生以下输出:

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

在报告的两个[eE]rrors 中,只有第二个是“正确的”R 错误对象,并且在变量query_result 中相应地捕获了try 的使用。

然而,我迫切希望捕获另一个 error 位 (no lines available in input) 以通知下游程序流程。

在玩了很多 capture.outputsinkpurrr::quietly 等通过 startpaging(谷歌搜索)找到的选项后,我仍然无法捕获该位。我该怎么做?

【问题讨论】:

  • 您尝试过“tryCatch”功能吗?通常比“尝试”效果更好。

标签: r error-handling


【解决方案1】:

正如@Csd 建议的那样,您可以使用tryCatch。您所追求的消息由 R 中的 message() 函数打印,而不是 stop(),因此 try() 将忽略它。要从message() 捕获输出,请使用如下代码:

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))

这将在收到任何消息时中止评估,并在query_results 中返回消息。如果您要做的不仅仅是调试,您可能希望保存消息,但继续评估。在这种情况下,请改用withCallingHandlers。例如,

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)))

当我运行这个版本时,query_results 没有改变(因为后面的错误中止了执行),但是消息被保存了:

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"

【讨论】:

  • 真的很酷 - 正确的轨道。现在即使出现错误(如尝试)如何继续?
  • 请参阅下面的答案,了解基于您出色观察的 UGLY 构造。
【解决方案2】:

基于@user2554330 的最佳答案,我构建了一个丑陋的东西,它完全符合我的要求:

  1. 尝试执行语句
  2. 不要失败
  3. 不要留下丑陋的信息
  4. 允许我访问errors 和messages

所以这就是它卑鄙的荣耀:

  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))))

【讨论】:

  • 我不会称之为“丑陋”。您想对消息和错误执行两种不同的操作:保存前者但继续计算,停止计算但为后者保存消息。所以你真的需要两个函数:try()tryCatch() 用于错误,withCallingHandlers 用于消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 2010-11-08
  • 1970-01-01
  • 2014-08-15
相关资源
最近更新 更多