我需要一个函数生成器,它接受另一个函数和该函数的任何参数并设置新的默认值。我认为@ hadley的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
答案 0 :(得分:7)
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"
答案 1 :(得分:5)
这是一个预制功能,它将@FrFlick的响应很好地转化为未来搜索者的功能:
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"
答案 2 :(得分:2)
你可以写一个简单的包装器
.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"