我在R中有一个调用其他函数的函数.有时,这些函数可能会返回相同的消息.我只想把这条消息打印一次.处理这一问题的最好方法是什么?

在下面的示例中,functionC将打印"the value is 5".两次,如果b和c的自变量是5.我只想打印一次.

functionA <- function(a){
  
  if(a==5){
    message("The value is 5.")
  }
  return(a-2)
}

functionB <- function(b){
  
  if(b==5){
    message("The value is 5.")
  }
  return(b+7)
}

functionC <- function(a,b){
  a <- functionA(a)
  b <- functionB(b)
  c <- rbind(a,b)
  return(c)
}

functionC(5,5)

推荐答案

您可以使用withCallingHandlers来实时捕获(和 suppress )消息,然后使用unique来减少它们,然后重新将它们释放出来.为了透明起见,重复使用时我会加上(n times)(否则您可能不清楚内部调用有多吵).

functionC <- function(a,b){
  msgs <- character(0)
  a <- withCallingHandlers(
    functionA(a),
    message = function(m) {
      msgs <<- c(msgs, conditionMessage(m))
      invokeRestart("muffleMessage")
    })
  b <- withCallingHandlers(
    functionB(b),
    message = function(m) {
      msgs <<- c(msgs, conditionMessage(m))
      invokeRestart("muffleMessage")
    })
  msgs <- trimws(msgs)
  # since 'table' does not preserve the original order, we'll do a few
  # extra steps to ensure the messages appear in the order of their
  # _first_ appearance
  counts <- table(msgs)
  counts <- counts[match(names(counts), msgs)]
  msgs <- paste0(names(counts), ifelse(counts > 1, sprintf(" (%d times)", counts), ""))
  for (m in msgs) message(m)
  c <- rbind(a, b)
  return(c)
}
functionC(5,5)
# The value is 5. (2 times)
#   [,1]
# a    3
# b   12

您可以重复message=/"muffleMessage"warning=/"muffleWarning"来捕捉警告...不过,您也可以使用purrr::quietly:

functionC2 <- function(a,b){
  msgs <- character(0)
  warns <- character(0)
  aout <- purrr::quietly(functionA)(a)
  bout <- purrr::quietly(functionB)(b)
  fewer <- function(z) {
    z <- trimws(z)
    counts <- table(z)
    counts <- counts[match(names(counts), z)]
    paste0(names(counts), ifelse(counts > 1, sprintf(" (%d times)", counts), ""))
  }
  msgs <- fewer(c(aout$messages, bout$messages))
  warns <- fewer(c(aout$warnings, bout$warnings))
  cout <- rbind(aout$result, bout$result)
  for (m in msgs) message(m)
  for (w in warns) warning(w)
  return(cout)
}

R相关问答推荐

如何从使用lapply()的r中的拆分数据帧中删除多个部分?

如何按行和列组合多个格式?

在R中使用GG Plot时如何 suppress 等值线图中的彩色条

通过Plotly绘制线串几何形状的3D图

工作流程_set带有Dplyrr风格的 Select 器,用于 Select 结果和预测因子R

如何使用shinyChatR包配置聊天机器人

计算R中的威布尔分布的EDF

如何根据R中其他列的值有条件地从列中提取数据?

根据日期从参考帧中创建不同的帧

在RStudio中堆叠条形图和折线图

在R gggplot2中是否有一种方法将绘图轴转换成连续的 colored颜色 尺度?

如何通过判断数据框的一列来压缩另一列?

函数可以跨多个列搜索多个字符串并创建二进制输出变量

自定义gggraph,使geom_abline图层仅在沿x轴的特定范围内显示

如何使用前缀作为匹配来连接数据帧?

R代码,用于在线条图下显示观测表

使用gt_summary是否有一种方法来限制每个变量集进行配对比较?

ArrangeGrob()和类似的替代方法不接受Grob列表.在Grid.Draw,返回:glist中的错误(...):仅允许在glist";中使用Grobs;

生存时间序列的逻辑检验

R try Catch in the loop-跳过缺少的值并创建一个DF,显示跳过的内容