将不带引号的列名称向量传递给函数并使用第一个元素

问题描述 投票:0回答:2

这按预期工作:

library(dplyr)

f <- function(x = c(am, vs)) 
  mtcars %>% 
    select({{x}})

我如何重写该函数(我们称之为

f2
),使得
f2
仅选择x的第一个元素,即
f2()
最终应该与
mtcars %>% select(am)
相同?

一些要求:

  • 我确实想将列作为向量传递,因此使用
    ...
    的解决方案在我的情况下不起作用。
  • 我想留在 tidyverse 语法中并希望传递不带引号的列名称,即使用
    x = c("am", "vs")
    也不是所希望的。
r tidyverse tidyselect
2个回答
5
投票

tidyselect::eval_select()
返回
select()
使用的索引向量,也可以是子集,因此一种方法可能是:

library(tidyselect)
library(dplyr)

f2 <- function(x = c(am, vs)) {
mtcars %>%
    select(first(eval_select(expr({{x}}), data = .)))
}

f2() |>
  names()

[1] "am"

0
投票

另外两种方法:

  1. (改编自此处

    library(rlang)
    
    f1 <- function(x = c(am, vs)){
      var_names <- enquo(x) |> 
        quo_name() |>
        gsub(pattern = '(c\\(|\\)|\\s)', replacement = '') |> 
        strsplit(split = ',') |> 
        unlist()
      mtcars |> select(var_names[1])
    }

  1. 或者简单地说:

    f2 <- function(x = c(am, vs)){
      mtcars |> select({{x}}) |> select(1)
    }

> identical(f1(), f2())
[1] TRUE
© www.soinside.com 2019 - 2024. All rights reserved.