Генерация функций; изменить значения по умолчанию других функций (частичные)
Мне нужен генератор функций, который принимает другую функцию и любые аргументы этой функции и устанавливает новые значения по умолчанию. Я думал @ хэдли pryr::partial
была эта магическая функция. Он делает именно то, что я хочу, но вы не можете изменить это новое значение по умолчанию. Так что здесь я могу изменить sep
в моем новом paste
функция, но не новый по умолчанию collapse = "_BAR_"
, Как я могу сделать partial
выполнить таким образом (т.е. по умолчанию collapse = "_BAR_"
но включите настройку collapse = NULL
при желании)? Если это невозможно с partial
Есть ли способ переписать код для partial
Для этого: https://github.com/hadley/pryr/blob/master/R/partial.r
library(pryr)
.paste <- pryr::partial(paste, collapse = "_FOO_")
.paste(1:5)
.paste(1:5, LETTERS[1:5], sep="_BAR_")
.paste(1:5, collapse=NULL)
> .paste(1:5)
[1] "1_FOO_2_FOO_3_FOO_4_FOO_5"
> .paste(1:5, LETTERS[1:5], sep="_BAR_")
[1] "1_BAR_A_FOO_2_BAR_B_FOO_3_BAR_C_FOO_4_BAR_D_FOO_5_BAR_E"
> .paste(1:5, collapse=NULL)
Error in paste(collapse = "_FOO_", ...) :
formal argument "collapse" matched by multiple actual arguments
3 ответа
partial
подходит для фиксирования определенных значений параметров, но если вы хотите изменить значения по умолчанию, вы можете рассмотреть другую стратегию. Это будет работать
.paste <- paste
formals(.paste)$collapse <- "_FOO_"
Это изменяет параметры функции
args(.paste)
# function (..., sep = " ", collapse = "_FOO_")
# NULL
Тогда вы можете сделать
.paste(1:5)
# [1] "1_FOO_2_FOO_3_FOO_4_FOO_5"
.paste(1:5, LETTERS[1:5], sep="_BAR_")
# [1] "1_BAR_A_FOO_2_BAR_B_FOO_3_BAR_C_FOO_4_BAR_D_FOO_5_BAR_E"
.paste(1:5, collapse=NULL)
# [1] "1" "2" "3" "4" "5"
Это постоянная функция, принимающая отличный ответ @MrFlick и включающая его в функцию для будущих поисковиков:
hijack <- function(FUN, ...){
.FUN <- FUN
args <- list(...)
invisible(lapply(seq_along(args), function(i) {
formals(.FUN)[[names(args)[i]]] <<- args[[i]]
}))
.FUN
}
# Теперь попробуйте
.paste <- hijack(paste, collapse = "_FOO_")
.paste(1:5)
.paste(1:5, LETTERS[1:5], sep="_BAR_")
.paste(1:5, collapse=NULL)
Уступая
> .paste(1:5)
[1] "1_FOO_2_FOO_3_FOO_4_FOO_5"
> .paste(1:5, LETTERS[1:5], sep="_BAR_")
[1] "1_BAR_A_FOO_2_BAR_B_FOO_3_BAR_C_FOO_4_BAR_D_FOO_5_BAR_E"
> .paste(1:5, collapse=NULL)
[1] "1" "2" "3" "4" "5"
Вы могли бы просто написать простую обертку
.paste <- function(..., collapse = "_FOO_"){paste(..., collapse = collapse)}
который дает
> .paste <- function(..., collapse = "_FOO_"){paste(..., collapse = collapse)}
> .paste(1:5)
[1] "1_FOO_2_FOO_3_FOO_4_FOO_5"
> .paste(1:5, collapse = NULL)
[1] "1" "2" "3" "4" "5"