如何在R的CLI错误消息中精准展示...参数的传入内容
解决方案
1. 简洁显示筛选条件
使用rlang::exprs()捕获传入...的表达式,再通过purrr::map_chr()配合rlang::expr_text()转换为干净的文本格式,最后用逗号拼接即可去除冗余符号:
library(dplyr) library(cli) library(rlang) library(purrr) filter_to_one <- function(df, ...) { filter_exprs <- exprs(...) filtered <- df |> filter(!!!filter_exprs) n <- nrow(filtered) if (n != 1) { criteria <- map_chr(filter_exprs, expr_text) |> paste(collapse = ", ") cli_abort( c("Did not find one unique match, found {n}.", "i" = "filter criteria: {criteria}" ) ) } else { filtered } } mtcars |> filter_to_one(cyl == 6 & gear == 4, mpg > 20) #> Error in `filter_to_one()`: #> ! Did not find one unique match, found 2. #> ℹ filter criteria: cyl == 6 & gear == 4, mpg > 20
2. 重现完整函数调用
通过rlang::call2()构造完整的函数调用表达式,再用rlang::expr_text()转换为可读文本,无需字符串拼接即可精准还原调用:
基础版(含数据框参数)
library(dplyr) library(cli) library(rlang) filter_to_one <- function(df, ...) { filtered <- df |> filter(...) n <- nrow(filtered) if (n != 1) { full_call <- call2("filter_to_one", enexpr(df), ...) call_text <- expr_text(full_call) cli_abort( c("Did not find one unique match, found {n}.", "i" = "call: {call_text}" ) ) } else { filtered } } mtcars |> filter_to_one(cyl == 6 & gear == 4, mpg > 20) #> Error in `filter_to_one()`: #> ! Did not find one unique match, found 2. #> ℹ call: filter_to_one(mtcars, cyl == 6 & gear == 4, mpg > 20)
管道调用还原版
如果想贴近原代码的管道写法,用rlang::expr()构造管道表达式:
library(dplyr) library(cli) library(rlang) filter_to_one <- function(df, ...) { filtered <- df |> filter(...) n <- nrow(filtered) if (n != 1) { full_call <- expr(!!enexpr(df) |> filter_to_one(!!!exprs(...))) call_text <- expr_text(full_call) cli_abort( c("Did not find one unique match, found {n}.", "i" = "call: {call_text}" ) ) } else { filtered } } mtcars |> filter_to_one(cyl == 6 & gear == 4, mpg > 20) #> Error in `filter_to_one()`: #> ! Did not find one unique match, found 2. #> ℹ call: mtcars |> filter_to_one(cyl == 6 & gear == 4, mpg > 20)
内容的提问来源于stack exchange,提问作者mac
相关产品推荐
相关产品推荐

