You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R函数如何同时处理错误与警告并自动识别EventType?

问题描述

我编写的cohort_entry函数接收IndexEvent和IndexEventType两个参数。当用户未指定IndexEventType时,程序需要自动尝试所有可选的EventType,筛选出既不返回错误也不返回警告的类型(不匹配的EventType会抛出错误或警告)。

目前的问题是无法同时捕获错误与警告:使用tryCatch时只能先检查错误,无错误再检查警告,通过嵌套循环寻找符合条件的EventType,但我需要实现同时检测错误和警告的逻辑,而非分开处理。

现有代码
library(Capr)
cohort_entry <- function(IndexEventType = NA_character_,
                         IndexEvent){
  
  if(is.na(IndexEventType)) {
    e <- tryCatch(expr = condition(IndexEvent),
             error = function(e) {
               tryCatch(expr = condition(IndexEvent),
                        warning = function (w) {
                          tryCatch(expr = procedure(IndexEvent),
                                   error = function(e) {
                                     tryCatch(expr = procedure(IndexEvent),
                                              warning= function(w) {
                                                tryCatch(expr = visit(IndexEvent),
                                                         error = function(e) {
                                                           tryCatch(expr = visit(IndexEvent),
                                                                    warning = function(w) {
                                                                      tryCatch(expr = drug(IndexEvent),
                                                                               error = function(e) {
                                                                                 tryCatch(expr = drug(IndexEvent),
                                                                                          warning = function(w) {
                                                                                            finally = print("No Index Event Found")
                                                                                          })
                                                                               })
                                                                    })
                                                         })
                                              })
                                   })
                        })
             })
  } else {
    IndexEventType = as.character(IndexEventType)
    
    validDomains <- c("conditionEra",
                      "condition",
                      "death",
                      "drug",
                      "drugEra",
                      "measurement",
                      "observation",
                      "visit")
    
    stopifnot(IndexEventType %in% validDomains)
    
    e <- match.fun(IndexEventType)(conceptSet = IndexEvent)
  }
  
  e1 <- entry(e)

}



## 测试数据

c1 <-new("ConceptSet", id = "fa773477eb0c08e1b8d6c7fca590ec21", Name = "QF - Inpatient or Inpatient/ER visit", 
    Expression = list(new("ConceptSetItem", Concept = new("Concept", 
                                                          concept_id = 262L, concept_name = "Emergency Room and Inpatient Visit", 
                                                          standard_concept = "S", standard_concept_caption = "Standard", 
                                                          invalid_reason = "V", invalid_reason_caption = "Valid", 
                                                          concept_code = "ERIP", domain_id = "Visit", vocabulary_id = "Visit", 
                                                          concept_class_id = "Visit"), isExcluded = FALSE, includeDescendants = TRUE, 
                          includeMapped = FALSE), new("ConceptSetItem", Concept = new("Concept", 
                                                                                      concept_id = 8717L, concept_name = "Inpatient Hospital", 
                                                                                      standard_concept = "S", standard_concept_caption = "Standard", 
                                                                                      invalid_reason = "V", invalid_reason_caption = "Valid", 
                                                                                      concept_code = "21", domain_id = "Visit", vocabulary_id = "CMS Place of Service", 
                                                                                      concept_class_id = "Visit"), isExcluded = FALSE, includeDescendants = TRUE, 
                                                      includeMapped = FALSE), new("ConceptSetItem", Concept = new("Concept", 
                                                                                                                  concept_id = 9201L, concept_name = "Inpatient Visit", 
                                                                                                                  standard_concept = "S", standard_concept_caption = "Standard", 
                                                                                                                  invalid_reason = "V", invalid_reason_caption = "Valid", 
                                                                                                                  concept_code = "IP", domain_id = "Visit", vocabulary_id = "Visit", 
                                                                                                                  concept_class_id = "Visit"), isExcluded = FALSE, includeDescendants = TRUE, 
                                                                                  includeMapped = FALSE)))

# c1 属于 visit 类型的 EventType

ce1 <- cohort_entry(IndexEvent = c1, IndexEventType = "visit")
ce1@entryEvents[[1]]@domain

ce2 <- cohort_entry(IndexEvent = c1) # 未指定 IndexEventType 时,程序选了错误的EventType,因为只检测了错误没检测警告
ce2@entryEvents[[1]]@domain 

# 可选的EventType包括以下这些
condition(c1)
drug(c1)
procedure(c1)
解决方案

可以编写一个辅助函数,同时捕获执行表达式时的错误和警告,然后遍历所有有效EventType,找到第一个既无错误也无警告的执行结果。

改写后的函数

library(Capr)

# 辅助函数:同时捕获错误和警告,返回结果或状态
safe_exec <- function(expr) {
  result <- list(value = NULL, error = NULL, warning = NULL)
  withCallingHandlers(
    tryCatch({
      result$value <- expr
    }, error = function(e) {
      result$error <- e$message
    }),
    warning = function(w) {
      result$warning <- w$message
      invokeRestart("muffleWarning") # 抑制警告输出
    }
  )
  return(result)
}

cohort_entry <- function(IndexEventType = NA_character_, IndexEvent) {
  validDomains <- c("conditionEra", "condition", "death", "drug", 
                    "drugEra", "measurement", "observation", "visit")
  
  if (!is.na(IndexEventType)) {
    IndexEventType <- as.character(IndexEventType)
    stopifnot(IndexEventType %in% validDomains)
    e <- match.fun(IndexEventType)(conceptSet = IndexEvent)
  } else {
    # 遍历所有有效EventType,找到第一个无错无警告的
    e <- NULL
    for (domain in validDomains) {
      res <- safe_exec(match.fun(domain)(conceptSet = IndexEvent))
      if (is.null(res$error) && is.null(res$warning)) {
        e <- res$value
        break
      }
    }
    if (is.null(e)) {
      stop("No valid Index Event Type found")
    }
  }
  
  entry(e)
}

测试验证

运行测试代码:

# 指定EventType测试
ce1 <- cohort_entry(IndexEvent = c1, IndexEventType = "visit")
ce1@entryEvents[[1]]@domain # 应返回 "Visit"

# 自动检测EventType测试
ce2 <- cohort_entry(IndexEvent = c1)
ce2@entryEvents[[1]]@domain # 应正确返回 "Visit"

这个方案通过safe_exec函数同时捕获错误和警告,遍历所有有效EventType时直接判断是否符合"无错无警告"的条件,避免了原代码中嵌套tryCatch的混乱逻辑,同时保证了只会选择完全匹配的EventType。

内容的提问来源于stack exchange,提问作者sutsabs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:32:00