【问题标题】:Using `:=` from rlang to assign column names using lapply function inputs使用 rlang 中的 `:=` 使用 lapply 函数输入分配列名
【发布时间】:2020-05-12 12:47:51
【问题描述】:

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

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

> 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() 等尝试了多种变体,但无法完全找出正确的语法。

【问题讨论】:

    标签: r dplyr tidyverse rlang


    【解决方案1】:

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

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

    在base R中,我们可以做

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

    【讨论】:

    • 在真实情况下,我正在寻找部分匹配。
    • @Brandon So map_dfc(mycols, ~df %&gt;% transmute(!!.x := grepl(.x, groupA))) ?
    • 这样就行了!我将不得不做一些阅读以了解为什么使用 !! 在这里有效,但不在我最初尝试的表达式中。
    • 或者为什么,例如,这不起作用:map_dfc(mycols, data.frame(!!.x := grepl(.x, df$groupA))),这表明匿名函数在如何解释表达式方面存在一些不同?
    • 啊,我明白了。不错的接机,这有效:map_dfc(mycols, ~tibble(!!.x := grepl(.x, df$groupA))),就像这样:map_dfc(mycols, ~grepl(.x, df$groupA)),尽管我没有在一个命令中以这种方式获得名称。当我不得不加入一些东西以避免产生矩阵对象时,我最初使用data.frame 来简化我的一些其他代码,但是你的方法更简单。谢谢!
    猜你喜欢
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 2018-08-12
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多