![](/img/trans.png)
[英]setting a function argument default value as a variable value at the time of creation of the function
[英]R setting a new value to the default argument for a function
我已經在R中編寫了這樣的函數:
foo <- function(a, b = 1) {
...
}
但是現在我想更改默認參數b,例如:
foo(b = 2)
這是原則上的功能。 但是R不允許這樣做,這使我出錯。
我該如何解決?
您可以這樣調用foo
: foo(a, b = whatever)
如果您確實需要經常將默認b
更改為相同的值,則可以制作一個新的與foo
相關的函數。
您可以定義一個新函數:
# partially substitute in a `b` value
goo <- purrr::partial(foo, b = 2, .first = FALSE)
# or, a bit more explicitly,
hoo <- function(a) {foo(a, b = 2)}
或構造一個函數builder / factory ,使您可以根據需要構建盡可能多的foo相關函數
foo_builder <- function(b = 1) {
function(a) {
# your definition of foo goes here
blah <- blah_f(a, b)
}
}
現在您可以將b
值傳遞給foo_builder,它將把等效函數返回給foo(a, b = whatever_you_passed_to_foo_builder)
what_you_passed_to_foo_builder foo(a, b = whatever_you_passed_to_foo_builder)
goo <- foo_builder(2)
goo(a = ...)
例如,
foo_builder <- function(b = 1){
function(a){
message(b)
a + b
}
}
現在,當內部函數由foo_builder定義時,它將采用foo_builder
環境可用的b
值。 默認情況下為1,但可以更改。
例如,
# default
foo_builder()(1)
1
[1] 2
# with b=2 in the closure returned by foo_builder
b <- 2
fb <- foo_builder(b)
fb(1)
2
[1] 3
一個評論者建議,當您以這種方式進行閉包時,應強制對b
求值; 由於以下原因:
b <- 2
fb <- foo_builder(b)
b <- 3
fb(1)
# 3
# [1] 4
因此,也許重寫foo_builder:
foo_builder <- function(b = 1){
force(b)
function(a){
message(b)
a + b
}
}
您在foo(b = 2)
代碼是函數應用程序:如果一切都按預期工作,它將為您提供值而不是函數。
您可以使用formals
修改參數的默認值:
foo <- function(a, b = 1) {
a + b
}
formals(foo)$b <- 2
foo
#function (a, b = 2)
# {
# a + b
# }
如果您不想直接修改foo
,可以使用以下幾種方法:
1)先復制,然后再更改
foa <- foo
formals(foa)$b <- 42
有人可能會認為使用的"formals<-"
作為快捷方式,但可以復雜,因為你需要提供的參數完整列表(使用alist
而不是list
,因為前者可以采取空參數):
"formals<-"(foo, , list(b=2)) # trying it with `list`
function (b = 2) # we lost one argument!
{
a + b
}
"formals<-"(foo, , alist(a=, b=42)) # this one is better!
function (a, b = 42)
{
a + b
}
2)按照其他答案中的建議使用purr::partial
或function(a) foo(a,b=42)
。
3)第三種方式...實際上可以編寫一個非常簡單的函數(我將其稱為p2
),該函數可以更改函數的某些默認參數並返回更改后的函數:
p2 <- function(f, l){
formals(f)[names(l)] <- l
f
}
p2(foo, list(b=42)) # changing a default: function (a, b = 42) a+b
p2(foo, alist(b=)) # removing a default: function (a, b) a+b
p2(foo, list(c="bingo") # adding an argument: function (a, b = 2, c = "bingo") a+b
修改后的版本:
p3 <- function(f, ...){
l <- as.list(sys.call())[-(1L:2L)] # code from `alist`
formals(f)[names(l)] <- l
f
}
現在用法變得更短:
p3(foo, b=43) # function (a, b = 43) a+b
p3(foo, b=) # function(a,b) a+b
請注意, p2
和p3
無法與諸如mean
和min
類的通用函數一起正常工作。 這可能是purrr:partial
的代碼如此復雜的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.