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

在R语言中组合逻辑函数:构建pass_tests多测试验证函数

这事儿好办!我帮你写一个灵活好用的pass_tests函数,既能整合多个测试的结果,还能按需返回不同格式的汇总信息。

实现pass_tests函数的思路与代码

首先,我们的目标是让这个函数能接受任意多个测试函数(每个函数输入单个元素,返回TRUE/FALSE),对输入对象x的每个元素批量执行测试,最后把结果整理成易读的格式。

基础版函数实现

pass_tests <- function(x, ...) {
  # 收集所有传入的测试函数
  tests <- list(...)
  
  # 边界检查:至少要传一个测试函数
  if (length(tests) == 0) {
    stop("请至少传入一个测试函数!")
  }
  
  # 给测试函数命名:用户没命名的话自动生成
  test_names <- names(tests)
  if (is.null(test_names)) {
    test_names <- paste0("test_", seq_along(tests))
  }
  
  # 对x的每个元素,运行所有测试
  results <- lapply(x, function(element) {
    sapply(tests, function(test) test(element))
  })
  
  # 把结果转换成数据框,设置行列名提升可读性
  results_df <- do.call(rbind, results)
  rownames(results_df) <- names(x) %||% seq_along(x)
  colnames(results_df) <- test_names
  
  return(results_df)
}

代码解释

  • 收集测试函数:用list(...)接收用户传入的任意多个测试函数,用法非常直观,比如pass_tests(x, test1, test2)。
  • 命名处理:如果用户给测试函数指定了名字(比如pass_tests(x, is_num = is.numeric)),就用用户的命名;否则自动生成test_1、test_2这类默认名。
  • 批量执行测试:用lapply遍历x的每个元素,对每个元素用sapply运行所有测试,得到该元素的所有测试结果。
  • 结果整理:把分散的测试结果列表转换成数据框,行对应x的元素(保留原命名或用序号),列对应测试函数,一目了然。

示例用法

先定义几个测试函数:

# 测试是否为数值型
is_numeric <- function(x) is.numeric(x)
# 测试是否大于0
is_positive <- function(x) x > 0
# 测试是否为偶数(仅对整数生效)
is_even <- function(x) ifelse(is.integer(x), x %% 2 == 0, FALSE)

然后测试一个混合类型的列表:

x <- list(a = 5, b = "hello", c = -3, d = 4L)
pass_tests(x, is_numeric, is_positive, is_even)

输出结果:

is_numeric is_positive is_even
a        TRUE        TRUE   FALSE
b       FALSE       FALSE   FALSE
c        TRUE       FALSE   FALSE
d        TRUE        TRUE    TRUE

扩展版:支持不同汇总格式

如果需要更简洁的结果,可以给函数加个summary参数,支持返回通过测试的数量,或者是否通过所有测试:

pass_tests <- function(x, ..., summary = c("full", "pass_count", "all_passed")) {
  summary <- match.arg(summary)
  
  tests <- list(...)
  if (length(tests) == 0) {
    stop("请至少传入一个测试函数!")
  }
  
  test_names <- names(tests) %||% paste0("test_", seq_along(tests))
  
  results <- lapply(x, function(element) {
    sapply(tests, function(test) test(element))
  })
  
  results_df <- do.call(rbind, results)
  rownames(results_df) <- names(x) %||% seq_along(x)
  colnames(results_df) <- test_names
  
  # 根据summary参数返回不同格式
  switch(summary,
         "full" = results_df,
         "pass_count" = data.frame(pass_count = rowSums(results_df)),
         "all_passed" = data.frame(all_passed = apply(results_df, 1, all))
  )
}

扩展版示例

# 返回每个元素通过的测试数量
pass_tests(x, is_numeric, is_positive, is_even, summary = "pass_count")
# 返回是否通过所有测试
pass_tests(x, is_numeric, is_positive, is_even, summary = "all_passed")

输出分别是:

pass_count
a           2
b           0
c           1
d           3

和

all_passed
a       FALSE
b       FALSE
c       FALSE
d        TRUE

注意事项

  • 所有测试函数必须接受单个参数,并且返回TRUE或FALSE。
  • 不管x是列表还是向量,lapply都能正常处理(向量会被拆分成单个元素的列表)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:42:32