5

我需要一个函数生成器,它接受另一个函数和该函数的任何参数并设置新的默认值。我认为@hadley'spryr::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
4

3 回答 3

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"
于 2014-08-18T02:11:21.043 回答
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"
于 2014-08-18T14:58:18.767 回答
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"
于 2014-08-19T02:26:58.330 回答