我想使用dplyr
将编程选择的函数列表应用于数据框的每一列。为了便于说明,这是我的功能列表:
fun_list <- lapply(iris[-5], function(x) if(var(x) > 0.7) median else mean)
我认为这样可行:
iris %>% group_by(Species) %>% summarise_each_(funs_(fun_list), names(iris)[-5])
基于?funs_
,其中陈述了论据应该是:
由...指定的函数列表。函数本身,意思是
但这失败了,错误:
Error in UseMethod("as.lazy") :
no applicable method for 'as.lazy' applied to an object of class "function"
似乎funs_
实际上期望符号列表对应于在适当环境中定义的函数,而不是实际函数。在我的应用程序中虽然我只获取函数,而不是它们的符号名称(此外,函数可能是匿名的)。
有没有办法将实际功能传递给summarise_each
dplyr
?注意我正在寻找dplyr
答案,因为我知道如何用其他工具解决这个问题。
答案 0 :(得分:3)
如果fun_list
是一个函数列表,您可以在将它用于dplyr函数之前将其转换为&#34;惰性对象&#34; 的列表。
library(lazyeval)
fun_list2 <- lapply(fun_list, function(f) lazy(f(.)))
或
fun_list2 <- lapply(fun_list, function(f) lazy_(quote(f), env = environment()))
但我不确定这是否是100%防水方法。
基于注释(每列有一个函数):
dispatch <- lazy_(quote((fun_list[[as.character(substitute(.))]](.))), env = environment())
iris %>% group_by(Species) %>% summarise_each_(funs_(dispatch), names(iris)[-5])
这个想法是使用summarise_each_
但不是使用函数列表而是使用
单个调度功能。此函数采用变量,找到正确的
函数来自原始的fun_list(按其名称!)并使用该变量作为输入。
如果函数列表的名称匹配,则解决方案有效 变量的名称。
也可以动态定义调度和函数列表(在这种情况下) 环境不是全球性的):
get_dispatch <- function(fun_list) {
return(lazy_(quote((fun_list[[as.character(substitute(.))]](.))), env = environment()))
}
dispatch <- get_dispatch(lapply(iris[-5], function(x) if(var(x) > 0.7) median else mean))