【r<-高級(jí)|理論】R的函數(shù)

我們可以在參數(shù)列表中加上一個(gè)省略號(hào)(...)來(lái)方便地指定任意長(zhǎng)度的參數(shù)。

下面通過(guò)構(gòu)造一個(gè)函數(shù)來(lái)舉例說(shuō)明。這個(gè)函數(shù)的功能是打印出第一個(gè)參數(shù)的內(nèi)容,然后將剩下的所有參數(shù)傳遞給summary函數(shù)。

首先構(gòu)造一個(gè)函數(shù),它有一個(gè)參數(shù)x。這個(gè)函數(shù)的參數(shù)列表中還包含了一個(gè)省略號(hào),因此這個(gè)省略號(hào)將成為我們調(diào)用的summary函數(shù)的參數(shù)。

> v <- c(sqrt(1:100))
> f <- function(x, ...) { print(x); summary(...)}
> f("Here is the summary for v.", v, digits=2)
[1] "Here is the summary for v."
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    1.0     5.1     7.1     6.7     8.7    10.0 

我們可以發(fā)現(xiàn),x之后的所有參數(shù)都被傳進(jìn)了summary函數(shù)。

有時(shí)候我們想要知道這些可變參數(shù)列表的所有參數(shù)值,這時(shí)候我們需要做的是在函數(shù)內(nèi)部將對(duì)象...轉(zhuǎn)換為一個(gè)列表。

舉個(gè)例子,我們構(gòu)造一個(gè)函數(shù)然后對(duì)所有的參數(shù)進(jìn)行相加求和。

> addemup <- function(x, ...){
+   args <- list(...)
+   for (a in args) x <- x + a 
+   x
+ }
> addemup(1,1)
[1] 2
> addemup(1,2,3,4,5)
[1] 15

我們還可以通過(guò)..1,..2..9等直接引用列表...中的內(nèi)容。..1表示第一項(xiàng),..2表示第二項(xiàng),以此類推。這有點(diǎn)類似于shell中通過(guò)$引用相應(yīng)的參數(shù)。看來(lái)很多的編程語(yǔ)言都存有相同的參數(shù)傳遞機(jī)制。

函數(shù)的屬性

R中包含了一系列的函數(shù)用于提取函數(shù)類型對(duì)象的信息

args函數(shù)可以用來(lái)查看函數(shù)包含了哪些參數(shù),args返回一個(gè)函數(shù)類型的對(duì)象,函數(shù)體為NULL。

> args(sin)
function (x) 
NULL
> args('?')
function (e1, e2) 
NULL
> args(args)
function (name) 
NULL
> args(lm)
function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 
NULL

如果我們想要在R代碼中對(duì)函數(shù)的參數(shù)列表進(jìn)行操作,formals函數(shù)是一個(gè)很好的工具,它會(huì)返回一個(gè)配對(duì)列表對(duì)象(對(duì)應(yīng)參數(shù)名和設(shè)定的默認(rèn)參數(shù)值)。

注意,formals函數(shù)僅能運(yùn)行在R寫的函數(shù)上(類型為closure的對(duì)象),而不能在內(nèi)嵌函數(shù)(bulti-in function)上運(yùn)行。(可能是因?yàn)閮?nèi)嵌函數(shù)是C寫的吧)

> f <- function(x, y=1, z=2) {x+y+z}
> f.formals <- formals(f)
> f.formals
$x


$y
[1] 1

$z
[1] 2

我們還可以利用它來(lái)更改函數(shù)的形參。例如:

> f.formals$y <- 3
> formals(f) <- f.formals
> args(f)
function (x, y = 3, z = 2) 
NULL

R提供了一個(gè)非常方便的函數(shù)alist用來(lái)構(gòu)建參數(shù)列表。我們可以像定義函數(shù)一樣很簡(jiǎn)單地指定參數(shù)列表。(注意,如果參數(shù)沒(méi)有默認(rèn)值,我們不必給它指定一個(gè)值,但是必須包含等號(hào)。)

> f <- function(x, y=1, z=2) { x + y + z}
> formals(f) <- alist(x=, y=100, z=200)
> args(f)
function (x, y = 100, z = 200) 
NULL

R提供了與formals函數(shù)類似的函數(shù)body來(lái)返回函數(shù)的函數(shù)體:

> body(f)
{
    x + y + z
}

我們也可以將它放在賦值語(yǔ)句的左邊,通過(guò)賦值操作來(lái)改變函數(shù)體。

> f
function (x, y = 100, z = 200) 
{
    x + y + z
}
> body(f) <- expression({x * y * z})
> f
function (x, y = 100, z = 200) 
{
    x * y * z
}

注意,函數(shù)體的類型為expression,所以重新賦值時(shí),也必須為expression類型。

改變其他環(huán)境

這里介紹<<-操作符的使用:比如var <<- value,它會(huì)使解釋器首先在當(dāng)前環(huán)境中檢索尋找符號(hào)var。如果解釋器無(wú)法在當(dāng)前環(huán)境中找到符號(hào)var,那么接下來(lái)會(huì)在父環(huán)境中繼續(xù)尋找。解釋器將這樣遞歸地在各個(gè)環(huán)境中尋找直到找到該符號(hào)或到達(dá)全局環(huán)境。加入解釋器在到達(dá)全局環(huán)境時(shí)依然沒(méi)有找到var,那么R會(huì)在全局環(huán)境中指定var的值為value。

下面是一個(gè)例子:

> x 
錯(cuò)誤: 找不到對(duì)象'x'
> doesnt.assign.x <- function(i){ x <- i}
> doesnt.assign.x(4)
> x
錯(cuò)誤: 找不到對(duì)象'x'
> assign.x <- function(i){ x <<- i}
> assign.x(4)
> x
[1] 4


學(xué)習(xí)整理自《R核心技術(shù)手冊(cè)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容