我有:

df <- data_frame(
  a = 1:2,
  b = list(1:10, 4:40)
)


foo <- function(x) mean(unlist(x))

预期的工作如下:
df$b %>% foo

但是,我无法弄清楚需要对foo进行哪些修改才能使df %>% foo(b)工作。

最佳答案

您可以将...参数直接传递给varssummarise_at帮助器,例如

foo <- function(.tbl, ...){
    summarise_at(.tbl,
                 vars(...),
                 funs(mean(unlist(.))))
}

它适用于单个变量,是否列出列:
df %>% foo(b)
## # A tibble: 1 × 1
##          b
##      <dbl>
## 1 18.48936

或多个:
df %>% foo(a, b)
## # A tibble: 1 × 2
##       a        b
##   <dbl>    <dbl>
## 1   1.5 18.48936

要进一步了解NSE,请查看lazyeval,这是dplyr用于实现其NSE的软件包。

还要注意,dplyr的SE / NSE系统刚刚在开发版本中重建(尚未在CRAN上,并且尚未记录)。

加分:在R底下完成所有操作!
foo <- function(.tbl, ...){
    # collect dots as character vector
    cols <- as.character(substitute(list(...))[-1])
    cls <- class(.tbl)

    # handle grouped tibbles properly
    if('grouped_df' %in% cls){
        cls <- cls[which(cls != 'grouped_df')]    # drop grouping
        res <- aggregate(.tbl[cols],
                         .tbl[attr(.tbl, 'vars')],
                         FUN = function(x){mean(unlist(x))})
    } else {
        res <- as.data.frame(lapply(.tbl[cols], function(x){mean(unlist(x))}))
    }

    class(res) <- cls    # keep class (tibble, etc.)
    res
}

与列表列,组和多个列或组一起使用,保持类但删除分组:
df %>% foo(a, b)
## # A tibble: 1 × 2
##       a        b
##   <dbl>    <dbl>
## 1   1.5 18.48936

df %>% group_by(a) %>% foo(b)
## # A tibble: 2 × 2
##       a     b
##   <int> <dbl>
## 1     1   5.5
## 2     2  22.0

mtcars %>% foo(mpg, hp)
##        mpg       hp
## 1 20.09062 146.6875

mtcars %>% group_by(cyl, am) %>% foo(hp, mpg)
## # A tibble: 6 × 4
##     cyl    am        hp      mpg
##   <dbl> <dbl>     <dbl>    <dbl>
## 1     4     0  84.66667 22.90000
## 2     6     0 115.25000 19.12500
## 3     8     0 194.16667 15.05000
## 4     4     1  81.87500 28.07500
## 5     6     1 131.66667 20.56667
## 6     8     1 299.50000 15.40000

08-20 00:20