我想创建一个函数来判断向量中是否包含裸露的表达式.该函数应独立于输入数据的情况工作.

计算各种表达式的一个简单解决方案是使用tidyselect::eval_select().例如,这里有一个伪函数,它判断表达式是ab还是c.

is_abc <- function(...) {
  expr <- rlang::expr(c(...))
  data <- rlang::set_names(letters)
  out <- tidyselect::eval_select(expr, data)
  names(out) %in% letters[1:3]
}

is_abc(a, b, z)
#> [1]  TRUE  TRUE FALSE

is_abc(c(a, b, z))
#> [1]  TRUE  TRUE FALSE

reprex package(v2.0.1)于2023-12-27创建

问题是,我认为不可能在不编辑tidyselect::eval_select()(或使用特殊的 Select 帮助器)的情况下使其不区分大小写.

is_abc(c(a, B, z))
#> Error in `is_abc()`:
#> ! Can't subset columns that don't exist.
#> ✖ Column `B` doesn't exist.

或者,我可以使用rlang::enexprs()来获取符号列表,然后在更改大小写或与向量进行比较时将其转换为字符类型:

is_abc <- function(...) {
  exprs <- rlang::enexprs(...)
  tolower(exprs) %in% tolower(letters[1:3])
}

is_abc(a, b, z)
#> [1]  TRUE  TRUE FALSE

is_abc(a, B, z)
#> [1]  TRUE  TRUE FALSE

reprex package(v2.0.1)于2023-12-27创建

现在的问题是,这不适用于更复杂的表达式,因为这会将整个表达式转换为字符串:

is_abc(c(a, b, z))
#> [1] FALSE

这个问题有没有一个简单的解决方案,这样我就可以让一个函数在这两种情况下都工作,而不需要依赖于输入的大小写?

例如:

# desired behaviour

is_abc(c(a, B), z)
#> [1]  TRUE  TRUE FALSE

推荐答案

你可以在R基地做所有的事情:

is_abc <- function(...) {
  
  args <- substitute(...())
  recurse <- FALSE
  if(".recurse" %in% names(args)) {
    args <- args[-match(".recurse", names(args))]
    recurse <- TRUE
  }
  out <- unlist(lapply(args, function(x) {
    if(is.call(x)) {
      x <- as.list(x)
      if(!identical(x[[1]], quote(c))) {
        stop("is_abc does not know what to do with calls to function '", 
             as.character(x[[1]]), "'")
      }
      unlist(do.call("is_abc", c(x[-1], .recurse = 1)))
    } else as.character(x)
    }))
  
  if(recurse) toupper(out) else toupper(out) %in% c("A", "B", "C")
}

测试:

is_abc(a, b, z)
#> [1]  TRUE  TRUE FALSE

is_abc(A, b, z)
#> [1]  TRUE  TRUE FALSE

is_abc(c(a, b, z))
#> [1]  TRUE  TRUE FALSE

is_abc(c(a, B, z))
#> [1]  TRUE  TRUE FALSE

is_abc(c(a, B), z)
#> [1]  TRUE  TRUE FALSE

is_abc(a, b, c(z, c, c(a, b, c(z, y, c(a, b, c)))))
#> [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE

R相关问答推荐

导入到固定列宽的R中时出现问题

更改网格的crs以匹配简单要素点对象的crs

如何在R中正确对齐放射状图中的文本

如何将在HW上运行的R中的消息(错误、警告等)作为批处理任务输出

如何使用R Shiny中的条件面板仅隐藏和显示用户输入,同时仍允许运行基础计算?

更改编号列表的 colored颜色

使用R中相同值创建分组观测指标

如何利用模型函数在格图中添加双曲/指数曲线

将嵌套列表子集化为嵌套列表

在组中添加值增加和减少的行

使用整齐的计算(curl -curl )和杂音

如何通过ggplot2添加短轴和删除长轴?

将二进制数据库转换为频率表

计算数据帧中指定值之前的行数,仅基于每行之后的future 行,单位为r

使用RSelenium在R中抓取Reddit时捕获多个标签

变长向量的矢量化和

如何在使用Alpha时让geom_curve在箭头中显示恒定透明度

如何使用循环从R中的聚合函数创建列,而不会在名称中给出&q;$&q;?

roxygen2正在处理太多的文件

如果极点中存在部分匹配,则替换整个字符串