Динамические имена функций в R

#r

#r

Вопрос:

Что мне нужно сделать, так это использовать обе функции which.min and which.max в R в цикле.

Я мог бы просто использовать if оператор (т.е. if find_max_value == TRUE then which.max(…) else which.min(…)

но мне было интересно, есть ли способ действительно сделать имя функции динамическим. Например:

 min_or_max =  'max'
special_text = paste('which.',min_or_max,sep='')
special_text(df_results$point)
  

есть ли способ заставить приведенный выше текст работать?

Комментарии:

1. Вы можете вставлять вместе имена функций или объектов, но это, как правило, делает вещи очень хрупкими и сложными для отладки. Часто лучше передавать функции напрямую в качестве аргументов или использовать код управления / потока (операторы if и тому подобное) для обработки обращений.

Ответ №1:

Если вам нужно выбрать из списка возможных функций, лучше сохранить их в списке. Например

 funs <- list(max = which.max, min=which.min)
min_or_max =  'max'
funs[[min_or_max]](df_results$point)
  

Это намного безопаснее, чем пытаться использовать произвольные строки в качестве кода. Кроме того, вы можете проверить, существует ли правильное значение, прежде чем пытаться запустить код: min_or_max %in% names(funs)

Комментарии:

1. почему двойные скобки?

2. Двойные скобки вернут функцию из списка. Использование одиночных скобок приведет к подмножеству списка (возвращению списка).

Ответ №2:

Может do.call быть, это то, что вы ищете:

 min_or_max =  'max'
special_text = paste('which.',min_or_max,sep='')
do.call(special_text, list(mtcars$cyl))
#> [1] 5
  

Комментарии:

1. да, именно то, что мне нужно!

Ответ №3:

Мы можем использовать invoke из purrr

 library(purrr)
invoke(special_text, list(mtcars$cyl))
#[1] 5
  

Ответ №4:

Вы также можете использовать match.fun :

 match.fun(special_text)(mtcars$mpg)
#[1] 20

#Verifying the results
which.max(mtcars$mpg)
#[1] 20