我有一个使用dplyr汇总变量的函数。我希望能够将摘要函数的名称作为参数传递。下面的方法有效(使用match.fun)。我想知道是否有更好/更简单的方法?
ev.setDescription(request.getParameter("description"));
ev.setRoomNumber(request.getParameter("room"));
ev.setScreen(request.getParameter("screen"));
try {
String startDateStr = request.getParameter("startDate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date startDate = sdf.parse(startDateStr);
ev.setEventDate(startDate);
String endDateStr = request.getParameter("endDate");
Date endDate = sdf.parse(endDateStr);
ev.setEventEndDate(endDate);
} catch (ParseException ex) {
Logger.getLogger(ActionOnEventsController.class.getName()).log(Level.SEVERE, null, ex);
}
eDao.save(ev);
response.sendRedirect("userpanel");
答案 0 :(得分:3)
通常不需要在R中通过其名称传递函数 - 因为函数是第一类(ish),你几乎总是可以只传递函数本身!
例如:
library(dplyr)
# data to illustrate
iris <- iris[1:10, ]
iris$Sepal.Length[1:3] <- NA
# the custom summary function
custom_summary <- function(df, var, summary_func, ...){
var <- enquo(var)
df %>% summarize(res = summary_func(!!var, ...))
}
# check that we can pass params to `summary_func` via `...`:
custom_summary(iris, var=Sepal.Length, summary_func=mean)
custom_summary(iris, var=Sepal.Length, summary_func=mean, na.rm=TRUE)
# double-check result against same thing in global env:
iris %>% summarize(res = mean(Sepal.Length))
iris %>% summarize(res = mean(Sepal.Length, na.rm=TRUE))
请注意,虽然在dplyr::
中将列名传递给函数是令人讨厌和复杂的,但将函数作为参数传递给其他函数在R中是很自然的事情。特别是当与magrittr::
管道结合使用时,这可以实现超紧凑的摘要。只举一个例子:
funcs <- c(mean=mean, mdn=median, lu=function(x) length(unique(x)))
cols <- c("Petal.Length", "Petal.Width", "Sepal.Length", "Sepal.Width")
funcs %>% sapply(function(f) iris[, cols] %>% sapply(f))
## mean mdn lu
## Petal.Length 3.758000 4.35 43
## Petal.Width 1.199333 1.30 22
## Sepal.Length 5.843333 5.80 35
## Sepal.Width 3.057333 3.00 23
答案 1 :(得分:1)
您可以使用summarize_at
exampleFunction2 <- function(df, var, function_name, ...){
var <- enquo(var)
results <- df %>%
summarize_at(vars(!!var), .funs = function_name,...) %>%
setNames("result")
}
identical(exampleFunction2(iris, Sepal.Width, "mean"),
exampleFunction(iris, Sepal.Width, "mean"))
# [1] TRUE