函数中的 dplyr 管道

dplyr pipeline in a function

我正在尝试将 dplyr 管道放入函数中,但在多次阅读小插图以及整洁的评估后 (https://tidyeval.tidyverse.org/dplyr.html)。 我仍然无法让它工作...

#Sample data:
dat <- read.table(text = "A ID B
1   X   83
2   X   NA
3   X   NA
4   Y   NA
5   X   2
6   Y   2
12   Y   10
7   Y   18
8   Y   85", header = TRUE)

# What I'm trying to do:
x <- dat %>% filter(!is.na(B)) %>% count('ID') %>% filter(freq>3)
x$ID

# Now in a function:
n_occurences <- function(df, n, column){
  # Group by ID and return IDs with number of non-na > n in column
  column <- enquo(column)
  x <- df %>%
       filter(!is.na(!!column))  %>%
       count('ID') %>% filter(freq>n)
  x$ID
}

# Let's try:
col <- 'B'
n_occurences(dat, n=3, column = col)

没有错误,但是输出有误。这与整洁评估有关,但我无法理解它。

使用 rlang_0.40,我们可以使用 {{...}} 或 curly-curly 运算符

更轻松地完成此操作
library(rlang)
library(dplyr)
n_occurences <- function(df, n1, column){

 df %>%
   filter(!is.na({{column}}))  %>%
    count(ID) %>% 
    filter(n > n1) %>%
    pull(ID)

 }     

n_occurences(dat, n1 = 3, column = B)
#[1] Y
#Levels: X Y

如果我们打算传递带引号的字符串,将其转换为符号 (sym),然后进行求值 (!!)

n_occurences <- function(df, n1, column){

  column <- rlang::sym(column)
 df %>%
       filter(!is.na(!!column))  %>%
       count(ID) %>% 
       filter(n > n1) %>%
       pull(ID)

}


col <- 'B'
n_occurences(dat, n1=3, column = col)
#[1] Y
#Levels: X Y