我有:
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)
工作。 最佳答案
您可以将...
参数直接传递给vars
的summarise_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