使用 rlang 中的 `:=` 使用 lapply 函数输入分配列名

Using `:=` from rlang to assign column names using lapply function inputs

我正在尝试遍历 patterns/strings 的向量以匹配另一列中的字符串,并将结果分配给与正在搜索的模式同名的列。下面是一个简单的例子。

我知道这个例子很简单,但它捕获了产生我无法解决的错误的最小情况。

> library(rlang)
> library(stringr)
> library(dplyr)
> set.seed(5)
> df <- data.frame(
+   groupA = sample(x = LETTERS[1:6], size = 20, replace = TRUE),
+   id_col = 1:20
+ )
> 
> mycols <- c('A','C','D')
> 
> dfmatches <- 
+   lapply(mycols, function(icol) {
+   data.frame(!!icol := grepl(pattern = icol, x = df$groupA))
+ }) %>% 
+   cbind.data.frame()

这给了我错误:

 Error: `:=` can only be used within a quasiquoted argument

所需的输出将是 data.frame,如下所示:

> dfmatches
       A     C     D
1  FALSE FALSE FALSE
2  FALSE FALSE FALSE
3  FALSE FALSE FALSE
4  FALSE FALSE FALSE
5   TRUE FALSE FALSE
6  FALSE FALSE FALSE
7  FALSE FALSE  TRUE
8  FALSE FALSE FALSE
9  FALSE FALSE FALSE
10  TRUE FALSE FALSE
11 FALSE FALSE FALSE
12 FALSE  TRUE FALSE
13 FALSE FALSE FALSE
14 FALSE FALSE  TRUE
15 FALSE FALSE FALSE
16 FALSE FALSE FALSE
17 FALSE  TRUE FALSE
18 FALSE FALSE FALSE
19 FALSE FALSE  TRUE
20 FALSE FALSE FALSE

我已经使用 {{}}!! rlang::sym() 等尝试了多种变体,但无法完全找出正确的语法。

一种选择是使用 purrr 中的 map_dfc。另外我认为你不需要 grepl 因为我们在这里寻找完全匹配而不是部分匹配。

library(dplyr)
library(purrr)

map_dfc(mycols, ~df %>% transmute(!!.x := groupA == .x))

在基础 R 中,我们可以做到

setNames(do.call(cbind.data.frame, lapply(mycols, 
                 function(x) df$groupA == x)), mycols)