for 循环中已弃用的 SE dplyr 动词的替代方法是什么?

What is the alternative to deprecated SE dplyr verbs in a for loop?

我习惯在 for 循环中使用 dplyr 动词的 SE 版本,我想过渡到新的评估语义,但我正在努力。

在旧的 dplyr 版本中,我会做类似的事情:

df <- tribble(
  ~x, ~y, ~z,
  "a", 2, "dog",
  "b", 1, "cat",
  "a", 2,  "cat"
)

for (i in names(df %>% select(x,z))){
  print(count_(df,i))
}

# A tibble: 2 x 2
  x         n
  <chr> <int>
1 a         2
2 b         1
# A tibble: 2 x 2
  z         n
  <chr> <int>
1 cat       2
2 dog       1

我尝试了 quo/enquo/!!/!!! 的各种组合,但似乎无法使用 count() 使其工作。

for(nm in c("x", "z")){
    print(df %>% count(!!as.symbol(nm)))
}
## A tibble: 2 x 2
#  x         n
#  <chr> <int>
#1 a         2
#2 b         1
## A tibble: 2 x 2
#  z         n
#  <chr> <int>
#1 cat       2
#2 dog       1

sym把字符串变成符号,然后用!!把符号插入表达式

for (i in names(df %>% select(x,z))){
  print(count(df, !!sym(i)))
}

rlang 提供了一个数据代词 .data。这个代词在像你这里这样用字符串引用列名时特别有用。

您可以阅读有关 it/see 个示例的更多信息 at the rlang website and at the end of the rlang 0.4.0 release article

for (i in names(df %>% select(x,z))){
     print( count(df, .data[[i]]) )
}

有一个很棒的包叫做 wrapr,它有一个 let 的函数 "allows execution of arbitrary code with substituted variable names"。该代码比使用 !! 更冗长,但我发现它更容易理解并且不易出错。

df <- tibble::tribble(
  ~x, ~y, ~z,
  "a", 2, "dog",
  "b", 1, "cat",
  "a", 2,  "cat"
)

for (name in names(df)) {
  wrapr::let(
    alias = list(var = name),
    expr = {
        df %>%
          count(var) %>%
          print()
    }
  )
}
#> # A tibble: 2 x 2
#>   x         n
#>   <chr> <int>
#> 1 a         2
#> 2 b         1
#> # A tibble: 2 x 2
#>       y     n
#>   <dbl> <int>
#> 1     1     1
#> 2     2     2
#> # A tibble: 2 x 2
#>   z         n
#>   <chr> <int>
#> 1 cat       2
#> 2 dog       1