R: программное создание вызова функции

мне часто приходится создавать вызов функции внутри другой функции, которая затем должна быть оценена. Я склонен использовать eval(parse(text = "what_needs_to_be_done")) для этого с текстом, построенным с помощью paste0(). Однако это не кажется хорошим подходом. Вот пример:

select_data <- function(x, A = NULL, B = NULL, C = NULL) {
  kall <- as.list(match.call())
  vars <- names(kall)[names(kall) %in% c("A", "B", "C")]
  selection_criteria <- paste0(vars,  " == ", kall[vars], collapse = ", ")
  txt <- paste0("dplyr::filter(x, ", selection_criteria, ")")
  res <- eval(parse(text = txt))
  return(res)
}   

DF <- data.frame(A = c(1,1,2,2,3,3), B = c(1,2,1,2,1,2), C = c(1,1,1,2,2,2))
select_data(DF, A = 2, C = 2)

это только пример, в большинстве случаев строимая функция является более сложной и обширной. Однако пример показывает общую проблему. То, что я делаю сейчас, это первое paste0 вместе вызов функции, то, как я бы ввел его в консоль, а затем оценил его.

я подделал альтернативные подходы с substitute, lazyeval, bquote, но я не совсем понимаю, что они делают и поэтому не может заставить их работать.

можете ли вы помочь мне найти лучший способ структурировать вызов и впоследствии оценить его?

1 ответов


обновление 4.29.17 -- скоро будет выпущен dplyr 0.6.0 будет решать эти проблемы. Новые ответы были добавлены к вопросам ниже. Подробнее о программировании с dplyr,посмотреть виньетку.


у вас есть правильная идея. Возможно, вы сможете немного сократить код с помощью ?filter_ и аргумент точки ...:

select_data <- function(x, ...) {
  kall <- list(...)
  filter_(.data=x, paste0(names(kall), "==", unlist(kall), collapse="&"))
}
select_data(DF, A = 2, C = 2)
#   A B C
# 1 2 2 2

обновление

Программирование dplyr может быть очень сложным даже для промежуточных кодеров. Этот автор признался, что преимущества нестандартной оценки связаны со стоимостью сложности в отношении функционального программирования. Есть несколько пользователей SO, работающих с той же проблемой:

стандартная оценка в dplyr

функция dplyr не работает

использование функций dplyr в другой функции

основные функции dplyr в функции Pass аргументы для функций dplyr

dplyr: фильтр, где два столбца данных.рамки равны

были предприняты шаги для решения этих проблем. Есть виньетка, чтобы наметить основные исправления. Однако, на мой скромный взгляд, виньетка недостаточно объясняет функциональное программирование. Нет ни одной функции, написанной в качестве примера. Не устраняет привходящие примеры, которые обычно появляются. Надеюсь, с увеличением в вызовах для исправления NSE мы можем в конечном итоге получить достаточный ответ.

в качестве последнего примера беспорядка, который нестандартная оценка может вызвать в программировании, я попытался работать над решением для этого пользователя некоторое время безрезультатно. Он просто просит использовать summarise программно:

Подфункция в функции группировки с помощью dplyr