簡體   English   中英

R為函數的默認參數設置新值

[英]R setting a new value to the default argument for a function

我已經在R中編寫了這樣的函數:

foo <- function(a, b = 1) {
    ...
}

但是現在我想更改默認參數b,例如:

foo(b = 2)

這是原則上的功能。 但是R不允許這樣做,這使我出錯。

我該如何解決?

您可以這樣調用foofoo(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::partialfunction(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

請注意, p2p3無法與諸如meanmin類的通用函數一起正常工作。 這可能是purrr:partial的代碼如此復雜的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM