非标准求值函数中参数与列检查合并异常问题
问题解决:合并参数检查与列存在性检查函数的错误修复
问题原因
在combined_fun中先执行rlang::is_missing(x)这类检查时,R会优先对x参数求值。如果传入的是不存在的对象(比如banana),R会直接抛出“object 'banana' not found”错误,后续的列名检查逻辑根本没机会执行。而单独调用check_column时,rlang::enquo(x)会直接捕获传入的表达式(而非强制求值),所以不会触发这个提前报错。
修复方案
调整检查顺序:先通过enquo捕获所有参数的表达式,再检查是否缺失,最后验证列名是否存在。这样能避免参数被提前求值,确保自定义错误信息正常输出。
修复后的函数代码:
combined_fun <- function(df, x, y, z) { # 先捕获所有参数的表达式 quo_df <- rlang::enquo(df) quo_x <- rlang::enquo(x) quo_y <- rlang::enquo(y) quo_z <- rlang::enquo(z) # 检查参数是否缺失 if (rlang::is_missing(quo_df)) { cli::cli_abort("{.var df} must be supplied") } else if (rlang::is_missing(quo_x)) { cli::cli_abort("{.var x} must be supplied") } else if (rlang::is_missing(quo_y)) { cli::cli_abort("{.var y} must be supplied") } else if (rlang::is_missing(quo_z)) { cli::cli_abort("{.var z} must be supplied") } # 将表达式转为列名字符串 var_x <- rlang::as_label(quo_x) var_y <- rlang::as_label(quo_y) var_z <- rlang::as_label(quo_z) # 获取实际的df对象 df_obj <- rlang::eval_tidy(quo_df) # 检查列名是否存在 if (!var_x %in% colnames(df_obj)) { cli::cli_abort("{var_x} not found in object supplied in {.var df}") } else if (!var_y %in% colnames(df_obj)) { cli::cli_abort("{var_y} not found in object supplied in {.var df}") } else if (!var_z %in% colnames(df_obj)) { cli::cli_abort("{var_z} not found in object supplied in {.var df}") } # 所有检查通过后的后续逻辑(可自定义) message("All checks passed!") }
验证示例
# 创建测试数据框 test_df <- data.frame(a = 1:3, b = 4:6, c = 7:9) # 测试缺失参数 combined_fun(test_df, a, b) # 抛出"z must be supplied"错误 # 测试不存在的列 combined_fun(test_df, a, b, banana) # 抛出"banana not found..."自定义错误 # 测试正常情况 combined_fun(test_df, a, b, c) # 输出"All checks passed!"
内容的提问来源于stack exchange,提问作者jdenn0514
相关产品推荐
相关产品推荐

