R lazyeval:将参数传递给dplyr :: filter

时间:2017-05-17 08:00:38

标签: r filter parameters dplyr lazyeval

我认为这些问题还有其他多种变体(例如:hereherehere) - 甚至可能是某个地方的答案。

如何为过滤器功能提供参数。

library(dplyr)
library(lazyeval)
set.seed(10)
data <- data.frame(a=sample(1:10, 100, T))

如果我需要计算出数字1到10的出现次数并显示计数,比如说1,2和3,我会这样做:

data %>% 
  group_by(a) %>% 
  summarise(n = n()) %>% 
  filter(a < 4)

给予:

# A tibble: 3 × 2
      a     n
  <int> <int>
1     1    11
2     2     8
3     3    16

现在,我该怎么把它放到一个函数中? 这里grp是分组变量。

   fun <- function(d, grp, no){
      d %>% 
        group_by_(grp) %>% 
        summarise_(n = interp(~ n() )) %>%
        filter_( grp < no)
        # This final line instead also does not work:  
        # filter_(interp( grp < no), grp = as.name(grp))
    }

现在,

fun(data, 'a', 4)

给出:

# A tibble: 0 × 2
# ... with 2 variables: a <int>, n <int>

1 个答案:

答案 0 :(得分:4)

我们可以使用dplyr的devel版本中的quosures方法(即将发布0.6.0)

fun <- function(d, grp, no){
   grp <- enquo(grp)

   d %>% 
      group_by(UQ(grp)) %>% 
      summarise(n = n() )%>%
       filter(UQ(grp) < no)

}

fun(data, a, 4)
# A tibble: 3 x 2
#      a     n
#  <int> <int>
#1     1    11
#2     2     8
#3     3    16

我们使用enquo获取输入参数并将其转换为quosure,在group_by/summarise/mutate内,通过取消引用(UQ或{{1}来评估quosure })

上述函数也可以修改为带引号和不带引号的参数

!!