2017-08-30 88 views
0

當將R函數的默認參數y定義爲等於其他參數x時。例如:function(x,y=x)。我發現如果在使用我的默認參數(y)之前更改其他參數(x),它也會更改y的值。R:使用修改其他參數時修改的其他參數的默認值

我知道它與「延遲複製直到修改」有關,但這真的是所需的行爲嗎?

下文一個完整的例子:

oh_my <- function(x, y=x){ 
    x <- rev(x) 
    y <- rev(y) # the value of y here actually is rev of initial x! 
    print(y) 
} 
oh_my(1:5) 

[1] 1 2 3 4 5

一個簡單的解決辦法是:

ok <- function(x, y=NULL){ 
    if(is.null(y)){ 
     y<-x 
    } 
    x <- rev(x) 
    y <- rev(y) 
    print(y) 
} 
ok(1:5) 

[1] 5 4 3 2 1

但我其實喜歡在第一個選項(包括在自動生成的幫助文件中)默認顯而易見的事實。

的其它解決辦法是:

pfiouu <- function(x, y=x){ 
    y <- rev(y) # the value of y here actually is rev of initial x! 
    x <- rev(x) 
    print(y) 
} 

pfiouu(1:5)

[1] 5 4 3 2 1

但它確實似乎彆扭我pfiouuoh_my給出了不同的結果,因爲這兩個交換行沒有明確提到每個其他變量,但卻得到不同的結果!

我錯過了一個好的做法,可以保持默認的明顯並避免那種陷阱?

+1

您可以在函數體的開頭添加一個'force(y)'。這將觸發評估。 – MrFlick

+0

謝謝@MrFlick我應該添加作爲答案? – cmbarbu

回答

0

正如MrFlick所建議的,在功能開始時增加force(y)可以強制y的評估並防止這樣的問題。儘管R仍然處於開放狀態,但它在如此高級的編程語言中是一種理想的行爲。

no_surprise<- function(x, y=x){ 
    force(y) 
    x <- rev(x) 
    y <- rev(y) 
    print(y) 
} 
no_surprise(1:5) 

[1] 5 4 3 2 1

正如所預期的。