NextNotes,Previous(dir),Up(dir)_第1頁
NextNotes,Previous(dir),Up(dir)_第2頁
NextNotes,Previous(dir),Up(dir)_第3頁
NextNotes,Previous(dir),Up(dir)_第4頁
NextNotes,Previous(dir),Up(dir)_第5頁
已閱讀5頁,還剩66頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、Next: Notes, Previous: (dir), Up: (dir) R 語言定義本冊主要對 R 語言,賦值解釋(explaining evaluation),解析,面向?qū)ο缶幊蹋Z言上的計(jì)算等方面進(jìn)行一個(gè)介紹。 本文檔的當(dāng)前版本為0.01 草稿。該文檔譯自 R-2.3.1 文檔(2006年6月1日)。 丁國徽(ghding) 譯。 本文檔的一些發(fā)布信息放置在/R/R-doc/。 ISBN 3-900051-13-5 · Notes: 說明 · Introduction: 緒論 ·

2、Objects: 對象 · Evaluation of expressions: 表達(dá)式求值 · Functions: 函數(shù) · Object-oriented programming: 面向?qū)ο缶幊?· Computing on the language: 語言上的計(jì)算 · System and foreign language interfaces: 系統(tǒng)和其它語言的接口 · Exception handling: 異常處理 · Debugging: 調(diào)試 · Parser: 解析器 · Functi

3、on and Variable Index: 函數(shù)和變量索引 · Concept Index: 概念索引 · References: 參考文獻(xiàn) 1 緒論R 是為統(tǒng)計(jì)計(jì)算和圖形展示而設(shè)計(jì)的一個(gè)系統(tǒng)。它包括一種編程語言,高級別圖形展示函數(shù),和其它語言的接口以及調(diào)試工具。本手冊將會(huì)詳細(xì)描述和定義R語言。 R 是統(tǒng)計(jì)領(lǐng)域廣泛使用的誕生于 1980年左右的 S 語言的一個(gè)分支。 S的主要設(shè)計(jì)者John M. Chambers 因?yàn)镾語言方面的工作獲得了1998年 ACM 軟件系統(tǒng)獎(jiǎng)(ACM Software Systems Award)。 該語言的語法表面上類似 C,但在語義上是函數(shù)

4、設(shè)計(jì)語言的(functional programming language)的變種并且和Lisp 以及 APL有很強(qiáng)的兼容性。特別的是,它允許在“語言上計(jì)算”(computing on the language)。這使得它可以把表達(dá)式作為函數(shù)的輸入?yún)?shù),而這種做法對統(tǒng)計(jì)模擬和繪圖非常有用。 通過命令行運(yùn)行簡單的表達(dá)式可以充分地交互使用 R 的功能。 一些用戶可能這樣做就能滿足要求了,但還有一些用戶想編寫他們自己的函數(shù)。編寫函數(shù)的用戶要么用以一種特別的方式,系統(tǒng)化一些常常重復(fù)的工作或者為新的功能編寫擴(kuò)展包。 本手冊的目的是想記錄R語言的本質(zhì)。也就是它所工作的對象,表達(dá)式賦值過程的細(xì)節(jié)。這些內(nèi)容的

5、了解對編寫R函數(shù)非常有用。另外一些針對特定任務(wù)的主題,如繪圖,在本冊里面只是簡單描述,而在其它手冊里面有專門的論述。 盡管手冊中的大部分內(nèi)容同樣適用于S,但S和R還是有一些實(shí)質(zhì)上的差異。為了不至于混淆,我們集中描述R。 R 語言的設(shè)計(jì)包含了一系列亮點(diǎn),當(dāng)然也有讓用戶驚訝的公共缺陷。許多設(shè)計(jì)是基于底層的連貫性考慮,我們會(huì)在后面的行文中解釋。它還包括很多有用的快捷方式和特殊用法,使得用戶可以很簡潔的表述復(fù)雜的操作。一旦用戶熟悉底層的概念,這些用法將會(huì)變得非常的自然。在某些情況下,有多種方法完成同一件事情,但是其中有些技術(shù)依賴于語言的實(shí)現(xiàn),另外一些技術(shù)則是一個(gè)更高層次上的抽象。在這種情況下,我們會(huì)指

6、出首選的用法。 讀本冊前,我們假定用戶對R已經(jīng)有一定的了解。這不是一本R的入門讀物,而是一本程序員的參考手冊。其它文檔給出了互補(bǔ)的信息:特別 Preface (R Introduction) 給出 R 語言的入門介紹和 System and foreign language interfaces (Writing R Extensions) 詳細(xì)介紹如何用編譯好的代碼擴(kuò)充 R語言。 2 對象在所有編程語言中, 變量提供了一種訪問內(nèi)存中數(shù)據(jù)的方法。 R 沒有提供直接訪問計(jì)算機(jī)內(nèi)存的方法,但提供了許多我們稱之為對象的特殊數(shù)據(jù)結(jié)構(gòu)。 這些對象通過變量或者符號(symbol)訪問。不過在 R 語言里面

7、,符號本身就是對象并且和使用其它對象一樣的方式使用。這和許多其它語言不同,但有廣泛的影響。 在本章,我們會(huì)給出R里面各種數(shù)據(jù)結(jié)構(gòu)的初步描述。對這些數(shù)據(jù)結(jié)構(gòu)更為詳細(xì)的討論會(huì)在后面的章節(jié)中展開。 R語言特有的函數(shù) typeof 返回R對象的類型。注意在 R 底層的 C 代碼中,所有對象都是指向一個(gè)有類型定義 SEXPREC的結(jié)構(gòu)體(structure)的指針;不同的R數(shù)據(jù)類型在 C 里面用決定結(jié)構(gòu)體各部分信息的 SEXPTYPE 表示。 下面的表格描述了 typeof 可能的返回值以及它們的涵義。 NULL 空 symbol 一個(gè)變量名字 pairlist 成對列表對象 closure 一個(gè)函數(shù)

8、environment 一個(gè)環(huán)境 promise 一個(gè)用于實(shí)現(xiàn)悠閑賦值的對象 language 一個(gè) R 語言構(gòu)建 special 一個(gè)不可針對參數(shù)求值的內(nèi)置函數(shù) builtin 一個(gè)可針對參數(shù)求值的內(nèi)置函數(shù) logical 含邏輯值的向量 integer 含整數(shù)值的向量 double 含實(shí)數(shù)值的向量 complex 含復(fù)數(shù)值的向量 character 含字符值的向量 . 特定變量長度參數(shù) * any 一個(gè)可以匹配任何類型的特殊類型 * expression 一個(gè)表達(dá)式對象 list 一個(gè)列表 externalptr 一個(gè)外表指針對象 weakref 一個(gè)弱引用對象(a weak refere

9、nce object) raw 一個(gè)字節(jié)元素向量 我認(rèn)為用戶不用深入以*'標(biāo)記的條目,至少?zèng)]有想象的那么容易;但是可以多看一些例子。 根據(jù) Becker,Chambers & Wilks (1988)中的說明,函數(shù) mode 返回對象的 模式信息,并且和其它S語言的變種完全兼容。 最后,同樣基于Becker et al. (1988)的考慮,函數(shù)storage.mode返回其參數(shù)的存儲模式(storage mode)。該函數(shù)常常用于,在外部語言(如C或FORTRAN)中調(diào)用函數(shù)時(shí)確保R對象有被調(diào)用的程序所期望的數(shù)據(jù)對象。(在S語言里面,整數(shù)值或?qū)崝?shù)值向量都是 "num

10、eric"模式,因此它們的存儲模式需要區(qū)分。) > x <- 1:3 > typeof(x) 1 "integer" > mode(x) 1 "numeric" > storage.mode(x) 1 "integer"R 在計(jì)算過程中,對象常常需要強(qiáng)制轉(zhuǎn)換成 不同的類型(type)。有許多函數(shù)可用于顯式的強(qiáng)制轉(zhuǎn)換。 在僅僅用 R 語言編程的時(shí)候,一個(gè)對象的類型通常不會(huì)影響計(jì)算結(jié)果,但是當(dāng)混合使用外部編程語言或不同的操作系統(tǒng)時(shí),常常需要保證對象類型的正確。 · Basic types:

11、 基本類型 · Attributes: 屬性 · Special compound objects: 特殊的混合對象 2.1 基本類型· Vector objects: 向量對象 · List objects: 列表對象 · Language objects: 語言對象 · Expression objects: 表達(dá)式對象 · Function objects: 函數(shù)對象 · NULL object: 空對象 · Built-in objects and special forms: 內(nèi)置對象和特別形態(tài)

12、 · Promise objects: 允諾對象 · Dot-dot-dot: .對象 · Environment objects: 環(huán)境對象 · Pairlist objects: 成對列表對象 · Any-type: 任意類型 2.1.1 向量向量可以看著是由一系列包含數(shù)據(jù)的緊密聯(lián)結(jié)的單元格子構(gòu)成。這些單元格通過 類似x5的索引操作來訪問。更細(xì)節(jié)的內(nèi)容可以參考Indexing。 R 有六個(gè)基本(原子性')向量類型:邏輯型,整數(shù)型,實(shí)數(shù)型,復(fù)數(shù)型,字符串(字符)型和原味型(raw)。這些不同向量類型的模式和存儲模式如下表所示。 typ

13、eof mode storage.mode logical logical logical integer numeric integer double numeric double complex complex complex character character character raw raw raw 單個(gè)的數(shù)字,如 4.2,以及字符串,如"four point two",仍然是長度為1的向量,因?yàn)闆]有更基本的數(shù)據(jù)類型了。零長度向量是允許的(也是非常有用的)。 字符串向量的模式和存儲模式都是 "character"。字符向量的單個(gè)元素常常是字

14、符串。 2.1.2 列表列表 (“廣義向量”) 是另外一種數(shù)據(jù)存儲方式。列表含有元素,每一個(gè)元素可以是任意 R對象類型,也就是說,列表的各個(gè)元素可以是不同的數(shù)據(jù)類型。列表元素的訪問可以通過三個(gè)不同 索引操作實(shí)現(xiàn)。這些在 Indexing部分將會(huì)詳細(xì)介紹。 列表是向量,并且在不能使用列表時(shí),基本的向量類型可以轉(zhuǎn)換為原子向量。 2.1.3 語言對象三種對象類型構(gòu)成了 R 語言的全部。它們分別是調(diào)用類型(calls),表達(dá)式類型(expressions) 和命名類型(names)。 既然 R 有 "expression" 類型的對象,所以我們應(yīng)該盡量避免在其它地方使用“表達(dá)式”這

15、個(gè)詞。需要注意的是,語法上正確的表達(dá)式會(huì)被看作是程序語句(statements)。 這些對象分別有 "call", "expression",和 "name" 三種模式。 這些對象可以利用 quote 機(jī)制從表達(dá)式直接創(chuàng)建,并且可以通過函數(shù) as.list和 as.call 與列表相互轉(zhuǎn)換。 解析樹的分量可以通過標(biāo)準(zhǔn)的索引操作析取。 · Symbol objects: 符號對象 2.1.4 表達(dá)式對象在 R 里面,我們可以創(chuàng)建類型為 "expression" 的對象。一個(gè) 表達(dá)式(expression)含

16、有一個(gè)或多個(gè)程序語句。其中,程序語句(statement)指的是語法上正確的一群標(biāo)記的聚集。 表達(dá)式對象是一種特殊語言對象,它包含一些解析過但還未求值的R語句。相比其它語言對象,它的主要差別在于一個(gè)表達(dá)式對象可以包含多個(gè)同類型的表達(dá)式。另外一個(gè)更細(xì)微的差別是,"expression"類型的對象僅僅當(dāng)它顯式地傳遞給函數(shù)eval時(shí)才求值, 而其它語言對象可在一些意想不到的情況下求值。 表達(dá)式對象的操作行為非常像列表,它的元素訪問方式和列表元素的訪問方式一樣。 2.1.5 函數(shù)對象在 R 里面,函數(shù)是對象并且可以有許多和其它對象類似的操作方法。函數(shù)(更準(zhǔn)確地說是函數(shù)閉包(func

17、tion closure)有三個(gè)基本的組成部分:形式化的參數(shù)列表,功能實(shí)現(xiàn)的主體和 環(huán)境。參數(shù)列表是一個(gè)以逗號分割的參數(shù)的列表。 參數(shù)可以是符號,或者是symbol = default 的形式,或者是特殊參數(shù) .。第二種參數(shù)形式常常用于設(shè)置參數(shù)的默認(rèn)值。如果函數(shù)調(diào)用時(shí)參數(shù)缺省,該值會(huì)被采用。 .參數(shù)比較特殊,而且可以包含任意多的參數(shù)。它通常在參數(shù)個(gè)數(shù)未知或者某些參數(shù)會(huì)傳遞給其它函數(shù)的情況下使用。 功能實(shí)現(xiàn)的主體是解析過的 R 語句。它常常是大括弧里面的一系列程序語句。當(dāng)然,它也有可能是一個(gè)單獨(dú)的語句,一個(gè)符號,甚至是一個(gè)常量。 函數(shù)的環(huán)境 指的是當(dāng)一個(gè)函數(shù)被創(chuàng)建時(shí)所激活的環(huán)境。任何被該環(huán)境綁定

18、的符號都可以被函數(shù)調(diào)用和訪問。函數(shù)代碼及其對應(yīng)環(huán)境中綁定的東西構(gòu)成的組合體稱為函數(shù)閉包'(function closure)。該術(shù)語源自函數(shù)化編程理論(functional programming theory)。在本文檔中,我們主要使用術(shù)語函數(shù)',但使用閉包'(closure)來強(qiáng)調(diào)一個(gè)函數(shù)相關(guān)環(huán)境的重要性。 可以通過 formals, body,和 environment 三個(gè)構(gòu)造(這三個(gè)構(gòu)造也可用在賦值語句的左邊)來析取和操作閉包的三個(gè)部分。 最后一個(gè)構(gòu)造可以用來去掉不想要的環(huán)境捕獲物(environment capture)。 當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),一個(gè)新的環(huán)境(

19、稱為求值環(huán)境(evaluation environment)將會(huì)被創(chuàng)建。該環(huán)境的外圍(enclosure,見Environment objects)來自函數(shù)閉包的環(huán)境。這個(gè)新的環(huán)境最初由函數(shù)的未被求值的參數(shù)構(gòu)成;當(dāng)求值過程進(jìn)行時(shí),局部變量將會(huì)在該環(huán)境中創(chuàng)建。 可以方便地用as.list 和 as.function 將函數(shù)和列表結(jié)構(gòu)相互轉(zhuǎn)換。 這些方法可以用來實(shí)現(xiàn)和S兼容,但我們不推崇這樣使用。 2.1.6 空對象NULL 是一種非常特殊的對象。它用于表明一個(gè)對象不存在。注意不能混淆空對象與零長度的向量/列表。 NULL 對象沒有類型也沒有可以更改的特性。在R里面,只用NULL 對象允許被所有的

20、實(shí)例對象引用(唯一的一個(gè))。為了檢測一個(gè)對象是否是NULL,可以使用代碼is.null。你不可以設(shè)置NULL的屬性。 2.1.7 內(nèi)置對象和特別形態(tài)有兩種類型的對象含有R的內(nèi)置函數(shù), 就是代碼列表中顯示為 .Primitive 的部分。這兩種對象的差異在于參數(shù)的處理方式。內(nèi)置函數(shù)將對它們所有參數(shù)求值并且傳給原始的函數(shù),即 值調(diào)用(call-by-value)。而一些特別函數(shù)把沒有求值的表達(dá)式傳給內(nèi)部函數(shù)。 從R語言的角度來說,這些對象僅僅是另外一種函數(shù),只是它們的定義不能列出而已。函數(shù)typeof可以把它們與解釋型函數(shù)(interpreted function)區(qū)分開。 2.1.8 允諾對象允

21、諾對象(promise objects)是 R 的悠閑(lazy)求值機(jī)制的一部分。它們含有三個(gè)槽(slots):值,表達(dá)式和環(huán)境。 當(dāng)一個(gè)函數(shù) 被調(diào)用,首先參數(shù)匹配,然后每個(gè)形式參數(shù)都會(huì)被一個(gè)允諾約束。用作形似參數(shù)的表達(dá)式以及函數(shù)調(diào)用的環(huán)境的指針都保存在允諾里面。 直到該參數(shù)被訪問,才會(huì)有值關(guān)聯(lián)允諾。當(dāng)參數(shù)被訪問時(shí),保存的表達(dá)式會(huì)在保存的環(huán)境中求值,并返回結(jié)果。 結(jié)果同樣被允諾保存。函數(shù) substitute 會(huì)提取一個(gè)表達(dá)式槽里面的內(nèi)容。這使得程序員既可以訪問允諾相關(guān)的值也可以訪問相關(guān)的表達(dá)式。 在 R 語言里面,允諾對象常常是隱含的對象。(在以后的R發(fā)布版本中,它們相對R代碼是透明的,因

22、為它們總是在被訪問的時(shí)候求值。)實(shí)際的函數(shù)參數(shù)是這種類型的。函數(shù) delayedAssign 可以使一個(gè)允諾出現(xiàn)在表達(dá)式的外面。通常還沒有辦法在 R 代碼里面檢驗(yàn)一個(gè)對象是否是允諾,同時(shí)也沒有方法用 R 代碼確定一個(gè)允諾的環(huán)境。 2.1.9 .對象. 對象類型以列表形式保存。. 的分量在 C 代碼里面可以像常規(guī)的列表一樣訪問,但在解釋型的代碼里面不像一個(gè)對象那樣容易訪問。該對象可以捕獲作為一個(gè)列表,因此在函數(shù) table 的實(shí)現(xiàn)代碼中,我們可以看到下面的例子 args <- list(.) # . for (a in args) # .如果一個(gè)函數(shù)以 . 作為形式參數(shù),那么任何不匹配形式

23、參數(shù)的實(shí)際參數(shù)都將匹配.。 2.1.10 環(huán)境環(huán)境可以簡單地看作由兩部分組成。一個(gè)是包含“符號-值” 對集合的框架(frame) ,另一個(gè)是指向外圍環(huán)境的指針(又稱為(外圍)(enclosure)。當(dāng) R 搜索一個(gè)符號的值時(shí),框架將會(huì)被檢查。如果找到了一個(gè)匹配的符號,它的值將會(huì)被返回。如果找不到,外圍環(huán)境將會(huì)被訪問并且重復(fù)這個(gè)過程。環(huán)境形成一個(gè)樹形結(jié)構(gòu),而外圍起到一個(gè)父節(jié)點(diǎn)的角色。環(huán)境的樹結(jié)構(gòu)的根部是一個(gè)空的環(huán)境,可以通過沒有父節(jié)點(diǎn)的 emptyenv() 訪問。它是基本包環(huán)境的直接父節(jié)點(diǎn)(可以通過函數(shù)baseenv()訪問)。 以前, baseenv() 可以是 NULL,但從版本 2.3.

24、0 開始,不贊成用 NULL 作為環(huán)境。 環(huán)境通過函數(shù)調(diào)用隱式創(chuàng)建,這些內(nèi)容在 Function objects 和 Lexical environment部分將會(huì)描述。在這種情況下,環(huán)境含有函數(shù)的局部變量(包括參數(shù)),而它的外圍是當(dāng)前調(diào)用函數(shù)的環(huán)境。環(huán)境還可以直接通過 new.env 創(chuàng)建。 一個(gè)環(huán)境的框架內(nèi)容可以通過 ls,get,assign 以及 eval 和 evalq 訪問和操作。 函數(shù) parent.env 可以用于訪問一個(gè)環(huán)境的外圍。 和其它的 R 對象不一樣,環(huán)境不是通過拷貝一份新的傳遞給函數(shù)或者用于賦值操作中。因此,如果你將一個(gè)的環(huán)境賦給好幾個(gè)符號并且改變其中的一個(gè),那么其

25、它的也都會(huì)改變。特別是,把一個(gè)屬性賦給一個(gè)環(huán)境會(huì)導(dǎo)致一些非常奇異的事情。 2.1.11 成對列表對象成對列表對象和 Lisp 的點(diǎn)-對列表(dotted-pair list)類似。它們廣泛用于R的內(nèi)部。但很少見于解釋型的代碼里面,盡管它們被 formals 返回或通過函數(shù)pairlist創(chuàng)建。一個(gè)零長度的成對列表是 NULL,這和 Lisp 期望的一樣但與零長度列表不一樣。 每個(gè)這樣的對象有三個(gè)槽變量,CAR值,CDR值和TAG值。 TAG值是文本字符串,CAR和CDR分別表示一個(gè)以空對象作為終結(jié)符的列表的列表項(xiàng)目(頭)和剩余項(xiàng)目(尾)(CAR/CDR術(shù)語是傳統(tǒng)Lisp術(shù)語,最初用于60年代

26、IBM 電腦的寄存器)。 R 語言里面成對列表的操作和廣義向量(“列表”)完全一樣。特別的是,元素也是通過 方式訪問。由于廣義向量可以更為高效地應(yīng)用,一般不贊同使用成對列表。如果通過 R 訪問一個(gè)內(nèi)部的成對列表,我們常常把它轉(zhuǎn)換成廣義向量(包括取子集的操作)。 在很少情況下,用戶可以看到成對列表:其中一個(gè)例子是 .Options。 2.1.12 “任意” 類型事實(shí)上,不可能有一個(gè)對象是“任意”(any)類型的,但它仍然是一個(gè)合法的類型值。它用于一些特定環(huán)境中(非常非常地少),如as.vector(x, "any")表明沒有必要采用類型的強(qiáng)制轉(zhuǎn)換。 2.2 屬性除了 NULL

27、,所有對象有一個(gè)或多個(gè)相關(guān)屬性。屬性以列表形式保存,其中所有元素都有名字。屬性列表可以通過 attributes 得到或通過 attributes<- 設(shè)定。 單個(gè)的屬性分量可以通過 attr 和 attr<-訪問。 一些屬性有特別的訪問函數(shù) (如和因子相關(guān)的 levels<-),但這些只在可用的情況下才能使用。為了隱藏實(shí)現(xiàn)細(xì)節(jié),它們可以進(jìn)行一些額外的操作。 R 嘗試攔截對含有特別屬性的 attr<- 和 attributes<- 的調(diào)用,以強(qiáng)迫進(jìn)行一致性的檢驗(yàn)。 矩陣和數(shù)組是含有屬性dim及可選屬性dimnames的簡單向量。 屬性用于實(shí)現(xiàn) R 里面的類結(jié)構(gòu)。如

28、果一個(gè)對象有一個(gè)class屬性,那么該屬性將會(huì)在求值過程中被檢驗(yàn)。 R的類結(jié)構(gòu)會(huì)在 Object-oriented programming 部分仔細(xì)描述。 · Names: 名字 · Dimensions: 維度 · Dimnames: 維度名字 · Classes: 類 · Time series attributes: 時(shí)間序列屬性 2.2.1 名字如果存在names屬性,names屬性會(huì)為一個(gè)向量或列表中的每個(gè)元素加上標(biāo)簽。當(dāng)對象被打印時(shí),names屬性同樣用于為元素加上標(biāo)簽(在存在names屬性的情況下)。 names屬性還可以用作索引

29、,例如 quantile(x)"25%"。 可以通過 names 和 names<- 構(gòu)造取得和設(shè)置名字。 后者將會(huì)執(zhí)行必要的一致性檢驗(yàn)以保證名字屬性有適合的類型和長度。 成對列表和一維數(shù)組的處理比較特殊。對于成對列表對象,一個(gè)虛擬的names屬性將被使用;names屬性實(shí)際上通過列表分量的標(biāo)簽構(gòu)建。對于一維數(shù)組,names屬性事實(shí)上是訪問 dimnames1。 2.2.2 維度dim 屬性用于實(shí)現(xiàn)數(shù)組。數(shù)組的內(nèi)容保存在一個(gè)列優(yōu)先排列(column-major order)的向量中而 dim 屬性是一個(gè)指定數(shù)組各維度長度的整數(shù)向量。 R 保證了向量的長度是各維度長度的

30、乘積。一個(gè)或多個(gè)維度的長度可以為0。 向量和一維數(shù)組不一樣,因?yàn)楹笳哂虚L度為1的 dim 屬性,而前者沒有 dim 屬性。 2.2.3 維度名字?jǐn)?shù)組會(huì)利用由字符向量構(gòu)成的 dimnames 屬性給各個(gè)維度命名。 dimnames 列表自身也可能有名字,在打印數(shù)組的時(shí)候這個(gè)名字可用作維度名字(extent headings)。 2.2.4 類R有一個(gè)精心設(shè)計(jì)的類系統(tǒng)。它通過 class 屬性控制。該屬性是一個(gè)含有類列表的字符向量,這些類可以被對象繼承。這構(gòu)成了 R 里面“泛型方法”(generic methods)功能性的基礎(chǔ)。 該屬性可以沒有限制的被用戶虛擬訪問和操作。對于一個(gè)對象是否真的含有

31、類方法期望的組成要素是不會(huì)被檢驗(yàn)的。因此,改變 class 屬性需要小心一點(diǎn)。當(dāng)實(shí)在需要的時(shí)候,建議使用一些特別的創(chuàng)建和強(qiáng)制轉(zhuǎn)換函數(shù)。 2.2.5 時(shí)間序列屬性tsp屬性用來保存時(shí)間序列的參數(shù),起點(diǎn),終點(diǎn)和頻率。該構(gòu)造主要用于處理有周期性背景的序列數(shù)據(jù)(如月或季度數(shù)據(jù))。 2.3 特殊的復(fù)合對象· Factors: 因子 · Data frame objects: 數(shù)據(jù)框?qū)ο?2.3.1 因子因子可用于描述含有數(shù)目有限值(性別,社會(huì)階層等)的條目。因子有一個(gè)levels屬性和"factor"類。另外,它還可以擁有一個(gè)可選的 contrasts 屬性。 c

32、ontrasts 屬性用于控制模型構(gòu)建函數(shù)中的參數(shù)設(shè)置。 因子可能是完全無序的或者有序的分類。在后面的例子中,可以根據(jù)因子的不同類型定義并且有一個(gè)對應(yīng)的 class 向量 c("ordered"," factor")。 現(xiàn)在,因子通過指定實(shí)際水平的整型數(shù)組和一個(gè)映射整數(shù)到名字的字符數(shù)組來實(shí)現(xiàn)。不幸得是,用戶常常利用這種實(shí)現(xiàn)方式讓一些計(jì)算變得比較簡單。但是,這只是一個(gè)實(shí)現(xiàn)的問題,而不能保證R的所有實(shí)現(xiàn)中都可以這樣。 2.3.2 數(shù)據(jù)框?qū)ο髷?shù)據(jù)框是 R 里面模仿 SAS或SPSS 數(shù)據(jù)集最像的數(shù)據(jù)結(jié)構(gòu),即數(shù)據(jù)的“個(gè)體-變量”(cases by variabl

33、es)矩陣。 數(shù)據(jù)框是由長度一樣(如果是矩陣則是行數(shù)一致)的向量,因子和/或矩陣構(gòu)成的列表。此外,數(shù)據(jù)框通常有一個(gè) names 屬性來標(biāo)記變量和 s 屬性來標(biāo)記個(gè)體。 數(shù)據(jù)框可以包含一個(gè)同其它分量長度一致的列表。該列表可以包含不同長度的元素,這樣就提供了一種參差數(shù)組(ragged arrays)的數(shù)據(jù)結(jié)構(gòu)。但是在寫本文檔的時(shí)候,這種數(shù)組通常還不能正確處理。 3 表達(dá)式的求值當(dāng)用戶在命令行上鍵入一行命令(或者從文件中讀入一個(gè)表達(dá)式),首先該命令將會(huì)被解析成一個(gè)內(nèi)在的表述方式。 求值程序執(zhí)行解析后的 R 表達(dá)式并且返回表達(dá)式的值。所有表達(dá)式都有一個(gè)值。這就是 R 語言的核心。 本章

34、描述求值程序的基本機(jī)制,但不討論特定函數(shù)或者后面獨(dú)立章節(jié)將討論的函數(shù)組或者幫助文檔已經(jīng)提供足夠信息內(nèi)容。 用戶可以自己構(gòu)建表達(dá)式并對它們調(diào)用求值程序。 · Simple evaluation: 簡單求值 · Control structures: 控制結(jié)構(gòu) · Elementary arithmetic operations: 初等算術(shù)操作 · Indexing: 索引 · Scope of variables: 變量作用域 3.1 簡單求值· Constants: 常量 · Symbol lookup: 符號查找 

35、3; Function calls: 函數(shù)調(diào)用 · Operators: 操作符 3.1.1 常量任何直接在提示符下面鍵入的數(shù)字都是常量,且被求值。 > 1 1 1常量比較地單調(diào)。如果要做更多的事情,我們需要符號。 3.1.2 符號查找當(dāng)一個(gè)新的變量創(chuàng)建時(shí),它需要一個(gè)可以被引用的名字。通常,它還需要一個(gè)值。 名字本身就是 符號。當(dāng)一個(gè)符號被求值時(shí), 它的值就會(huì)被返回。 后面我們將會(huì)仔細(xì)解釋怎樣決定一個(gè)和符號相關(guān)的值。 在下面簡單的例子中,y是一個(gè)符號并且它的值是4。符號也是R對象,但是我們很少需要直接處理符號,除了“在語言上編程”(programming on the lang

36、uage)(Computing on the language)。 > y <- 4 > y 1 43.1.3 函數(shù)調(diào)用R里面的很多計(jì)算都有函數(shù)求值。我們也把這稱之為函數(shù) 調(diào)用(invocation)。函數(shù)調(diào)用通過名字和一個(gè)以逗號分割的參數(shù)列表來實(shí)現(xiàn)。 > mean(1:10) 1 5.5在這個(gè)例子中,函數(shù) mean 的調(diào)用過程中只有一個(gè)參數(shù),就是含有1到10之間整數(shù)的向量。 R 含有許多用于各種目的的函數(shù)。大多數(shù)用來產(chǎn)生一個(gè)屬于 R 對象的結(jié)果,但其它一些函數(shù)則利用了它們的副作用,如打印和繪圖函數(shù)。 函數(shù)調(diào)用可以用標(biāo)簽標(biāo)記的參數(shù)(或命名參數(shù)),而在plot(x, y,

37、 pch = 3)中,一些參數(shù)沒有標(biāo)簽,這些參數(shù)通過位置識別。此時(shí),函數(shù)必須通過參數(shù)在參數(shù)列表中所處的序列順序來判斷它們的意義。因此前面的例子中, x 表示橫坐標(biāo)變量,y表示縱坐標(biāo)變量。使用標(biāo)簽/名字對含有很多可選參數(shù)的函數(shù)非常方便。 一個(gè)特別的函數(shù)調(diào)用可以出現(xiàn)在賦值操作符的左邊,如下所示 > class(x) <- "foo"該語句實(shí)際所做的就是利用原始的對象和右邊部分調(diào)用函數(shù) class<-。該函數(shù)對對象進(jìn)行修改,返回結(jié)果存入原始變量。(至少在概念上,這就是所發(fā)生的事情??赡?,一些額外的努力將用于避免不必要的數(shù)據(jù)重復(fù)。) 3.1.4 操作符R 允許使用

38、 C 語言類似的操作符構(gòu)建算術(shù)表達(dá)式,例如, > 1 + 2 1 3表達(dá)式可以用括號合并成組,混以函數(shù)調(diào)用,然后以一種直接的方式賦給變量 > y <- 2 * (a + log(x)R 含有一系列操作符。它們?nèi)缦卤硭尽?- 減號,一元操作符或者二元操作符 + 加號,一元操作符或者二元操作符 ! 一元否操作符 波浪號,用于模型公式,既可以是一元操作符也可以是二元操作符 ? 幫助 : 序列,二元操作符(在模型公式中,表示交互效應(yīng)) * 乘法,二元操作符 / 除法,二元操作符 冪運(yùn)算符,二元操作符 %x% 特殊二元操作符,x可以被任意合法的名字替換 % 求模,二元操作符 %/%

39、整除,二元操作符 %*% 矩陣相乘,二元操作符 %o% 外積,二元操作符 %x% Kronecker乘積,二元操作符 %in% 匹配操作,二元操作符(在模型公式中,表示嵌套) < 小于,二元操作符 > 大于,二元操作符 = 等于,二元操作符 >= 大于等于,二元操作符 <= 小于等于,二元操作符 & 與操作,二元操作符,向量模式 && 與操作,二元操作符,不是向量模式 | 或操作,二元操作符,向量模式 | 或操作,二元操作符,不是向量模式 <- 左賦值,二元操作符 -> 右賦值,二元操作符 $ 列表子集,二元操作符 除了語法上,操作符

40、使用和函數(shù)調(diào)用沒有差異。事實(shí)上,x + y 和 "+"(x, y) 等價(jià)。注意既然 + 不是一個(gè)標(biāo)準(zhǔn)的函數(shù)名字,那么它就需要被引號括起來。 R 同時(shí)處理數(shù)據(jù)的整個(gè)向量,并且大多數(shù)元素操作符和基本的數(shù)學(xué)函數(shù)如 log是向量模式的(和上面表格中提示的一樣)。這意味著如果兩個(gè)一樣長度的向量相加會(huì)隱式依據(jù)向量索引循環(huán)計(jì)算得到一個(gè)含有元素方式加和結(jié)果的向量。這種用法同樣適合其它操作符,如-,*,和 /,以及可以推廣到更高維的結(jié)構(gòu)。需要注意的是,兩個(gè)矩陣的相乘不會(huì)得到通常的矩陣乘積(%*%操作符用于這種目的)。一些和向量操作相關(guān)的要點(diǎn)將會(huì)在 Elementary arithmetic

41、operations 部分討論。 為訪問向量的某個(gè)元素,我們常常使用 xi 語句。 > x <- rnorm(5) > x 1 -0.12526937 -0.27961154 -1.03718717 -0.08156527 1.37167090 > x2 1 -0.2796115列表分量則更多地用 x$a 和 xi 方式訪問。 > x <- options() > x$prompt 1 "> "索引構(gòu)造(Indexing constructs)同樣可以出現(xiàn)在一個(gè)賦值操作的右邊。 和其它操作符類似,索引實(shí)際上也是通過函數(shù)實(shí)現(xiàn),可

42、以用 ""(x, 2) 代替 x2。 R的索引操作含有許多高級特性。這部分內(nèi)容將在 Indexing部分進(jìn)一步描述。 3.2 控制結(jié)構(gòu)R里面的計(jì)算包括順序地對語句求值。程序語句,如 x<-1:10 或 mean(y),可以被分號或者新的一行分割。只要 整個(gè)語句在語法上是完整的,該語句就會(huì)被求值并且將 值返回。一個(gè)語句的求值結(jié)果可以看作是該語句的值1 這個(gè)值通常會(huì)賦給一個(gè)符號。 分號和換行符可以用來分隔程序語句。分號一般表示一個(gè)語句的結(jié)束而新的一行只是 有可能表示一個(gè)語句的結(jié)束。如果當(dāng)前語句在語法上還不完整,換行符會(huì)被求值程序忽略掉。如果會(huì)話(session)是交互式的

43、,提示符會(huì)從 > 變?yōu)?+。 > x <- 0; x + 5 1 5 > y <- 1:10 > 1; 2 1 1 1 2語句可以用 和 組合在一起。一組這樣的語句有時(shí)會(huì)被稱為句塊(block)。單個(gè)語句會(huì)在其語法完整后鍵入新的一行時(shí)求值。句塊不會(huì)求值,直到在一個(gè)封閉的大括號后面鍵入新的一行。這一節(jié)余下的部分,語句 要么指單個(gè)語句要么指句塊。 > x <- 0 + x + 5 + 1 5· if: if語句 · Looping: 循環(huán)控制 · repeat: repeat語句 · while: while語

44、句 · for: for語句 · switch: switch語句 Footnotes1 求值常常在一個(gè)環(huán)境中進(jìn)行。 具體參考 Scope of variables。3.2.1 if 語句if/else語句有條件地對兩個(gè)語句求值。該句式的條件語句會(huì)被求值,如果它的 值 是 TRUE 那么第一個(gè)語句將會(huì)被執(zhí)行;否則第二個(gè)語句會(huì)被執(zhí)行。 if/else 語句返回所選語句求值結(jié)果并作為它的值。語法形式為 if ( statement1 ) statement2 else statement3首先,statement1 被求值得到 value1。如果 value1 是一個(gè)首元素為

45、TRUE的邏輯向量,那么 statement2 將會(huì)被求值。如果value1的第一個(gè)元素是 FALSE 那么statement3 將會(huì)被求值。如果 value1是一個(gè)數(shù)值向量,那么 statement3 在 value1的第一個(gè)元素是零的時(shí)候求值,否則 statement2 將會(huì)被求值。只有 value1 的第一個(gè)元素才會(huì)被使用。其它元素都會(huì)被忽略的。如果 value1 是邏輯和數(shù)值向量以外的向量,將會(huì)返回錯(cuò)誤。 If/else 語句可以用來防止一些數(shù)值計(jì)算問題,如對負(fù)數(shù)進(jìn)行對數(shù)操作。因?yàn)?if/else 語句和其它語句一樣,你可以把它們的值賦給其它變量。下面的兩個(gè)例子等價(jià)。 > if(

46、 any(x <= 0) ) y <- log(1+x) else y <- log(x) > y <- if( any(x <= 0) ) log(1+x) else log(x)else 子句是可選的。 語句 if(any(x <= 0) x <- xx <= 0 是合法的。如果 if 語句不在一個(gè)句塊中,那么 else子句(假定存在)必須和 statement1在同一行。否則,在statement1后的新一行將產(chǎn)生一個(gè)語法上完整并會(huì)被求值的語句。 If/else 語句可以被嵌套。 if ( statement1 ) statement

47、2 else if ( statement3 ) statement4 else if ( statement5 ) statement6 else statement8一個(gè)偶數(shù)編號的語句將會(huì)被求值并且返回結(jié)果值。如果忽略可選的 else 子句,并且所有奇數(shù)編號的 statement 的值都是 FALSE,那么就沒有語句會(huì)被求值則返回NULL。 奇數(shù)編號的statement會(huì)依次求值,直到一個(gè)值為 TRUE,然后對應(yīng)的偶數(shù)編號的 statement 會(huì)被求值。在這個(gè)例子中,statement6 當(dāng)且僅當(dāng) statement1 為 FALSE, statement3 為 FALSE 和 stat

48、ement5 是 TRUE的情況下才會(huì)被求值。else if子句的數(shù)目是沒有限制的。 3.2.2 循環(huán)控制R 有三種語句實(shí)現(xiàn)顯式的循環(huán)控制。1 它們分別是 for, while 和 repeat。兩個(gè)內(nèi)置的構(gòu)造 next 和 break 提供了對求值過程額外的控制。這三個(gè)語句都返回最后語句的求值結(jié)果。因此,可以把這些語句的結(jié)果值賦給一個(gè)符號,盡管這種做法不太常見。 R 還提供了其它一些隱式的循環(huán)控制函數(shù),如 tapply,apply 和 lapply。此外,許多操作,特別算術(shù)操作,都是向量模式的,因此你可能不太需要使用循環(huán)。 有兩種語句可用于顯式地循環(huán)控制。它們是break 和 next。 b

49、reak 語句可以從當(dāng)前運(yùn)行的最內(nèi)部的循環(huán)里面跳出。 next 語句會(huì)導(dǎo)致控制立即返回到循環(huán)的起點(diǎn),循環(huán)的下一次重復(fù)(如還有重復(fù)的話)然后被執(zhí)行。當(dāng)前循環(huán)中, next 后面的語句不會(huì)被執(zhí)行。 Footnotes1 循環(huán)指的是對某個(gè)語句或者語句塊進(jìn)行循環(huán)求值。3.2.3 repeat 語句repeat 語句會(huì)重復(fù)對主體部分求值直到明確地要求退出。這就意味著你必須小心使用 repeat,因?yàn)榭赡軐?dǎo)致死循環(huán)。 repeat 循環(huán)的語法如下 repeat statement在使用 repeat 語句時(shí),statement 必須是一個(gè)句塊。另外,你需要執(zhí)行一些計(jì)算并且測試語句是否會(huì)從循環(huán)里面跳出。這樣

50、做通常需要兩條語句。 3.2.4 while語句while 語句和 repeat 語句非常的類似。 while 循環(huán)的語法如下 while ( statement1 ) statement2其中 statement1 會(huì)被求值,如果它的值是 TRUE那么 statement2 會(huì)被執(zhí)行。這個(gè)過程重復(fù)直到 statement1 的值是 FALSE。如果 statement2 從來都沒有被執(zhí)行, 那么 while語句返回NULL,否則它將會(huì)返回最后一次執(zhí)行 statement2 所得到的值。 3.2.5 for 語句for 循環(huán)的語法如下 for ( name in vector ) statem

51、ent1其中 vector 既可以是向量也可以是列表。vector 里面每個(gè)元素的值都會(huì)賦給變量 name,然后執(zhí)行statement1。一個(gè)副作用是循環(huán)結(jié)束后,變量 name在循環(huán)退出后仍存在,并且它的值就是 vector 最后一個(gè)元素的值。 3.2.6 switch 語句技術(shù)層面上來說,switch 僅僅是一個(gè)函數(shù),但是它的語義學(xué)定義和其它程序語句的控制結(jié)構(gòu)類似。 它的語法如下 switch (statement, list)其中 list 的元素可能有自己的名字。首先,statement 被求值得到結(jié)果 value。如果 value 是 1 到 list長度間的一個(gè)數(shù)字,那么list對應(yīng)

52、元素將會(huì)被求值并返回結(jié)果。如果 value 值過大或者過小, NULL 將會(huì)被返回。 > x <- 3 > switch(x, 2+2, mean(1:10), rnorm(5) 1 2.2903605 2.3271663 -0.7060073 1.3622045 -0.2892720 > switch(2, 2+2, mean(1:10), rnorm(5) 1 5.5 > switch(6, 2+2, mean(1:10), rnorm(5) NULL如果 value 是字符向量,那么 . 的元素中名字和 value 準(zhǔn)確匹配的元素會(huì)被執(zhí)行。如果沒有匹配的,返

53、回 NULL。 > y <- "fruit" > switch(y, fruit = "banana", vegetable = "broccoli", meat = "beef") 1 "banana"switch 常用來根據(jù)函數(shù)一個(gè)參數(shù)的字符值決定后面的執(zhí)行語句。 > centre <- function(x, type) + switch(type, + mean = mean(x), + median = median(x), + trimmed = mea

54、n(x, trim = .1) + > x <- rcauchy(10) > centre(x, "mean") 1 0.8760325 > centre(x, "median") 1 0.5360891 > centre(x, "trimmed") 1 0.6086504switch 返回值要么是語句的求值結(jié)果要么在沒有語句被求值時(shí)的NULL。 為了從一個(gè)已經(jīng)存在的可選方法列表里面選擇一個(gè),switch 可能不是最好的實(shí)現(xiàn)方案。通常,用 eval 和 子集操作符 直接運(yùn)行 eval(xcondition

55、) 會(huì)更好。 3.3 初等算術(shù)操作· Recycling rules: 循環(huán)使用規(guī)則 · Propagation of names: 名字?jǐn)U散 · Dimensional attributes: 維度屬性 · NA handling: NA 處理 在本節(jié),我們將會(huì)討論用于基本操作符(如兩個(gè)向量或矩陣的加法和乘法)的一些規(guī)則要點(diǎn)。 3.3.1 循環(huán)使用規(guī)則如果兩個(gè)元素個(gè)數(shù)不一致的數(shù)據(jù)結(jié)構(gòu)相加,那么短的那個(gè)結(jié)構(gòu)會(huì)循環(huán)使用以達(dá)到長的結(jié)構(gòu)的長度。例如,將c(1, 2, 3) 和一個(gè)6元素長度的向量相加,你實(shí)際操作的是 c(1, 2, 3, 1, 2, 3)。如果

56、長向量的長度不是短向量的倍數(shù),一個(gè)警告將會(huì)給出。 從 R 1.4.0 開始,任何含零長度向量的算術(shù)操作結(jié)果都是零長度向量。 一個(gè)例外是,當(dāng)一個(gè)向量和矩陣相加的時(shí)候,如果長度不協(xié)調(diào),不會(huì)給出任何警告。 3.3.2 名字?jǐn)U散名字?jǐn)U散(第一個(gè)名字優(yōu)先。如果它沒有名字的,是不是也這樣? 第一個(gè)*擁有名字*的優(yōu)先,循環(huán)使用導(dǎo)致短的結(jié)構(gòu)丟失名字)。1 Footnotes1 譯者注:原句為“propagation of names (first one wins, I think - also if it has no names? first one *with names* wins, recyclin

57、g causes shortest to lose names)”3.3.3 維度屬性(矩陣+矩陣,維度必須匹配。向量+矩陣:第一個(gè)重復(fù)使用,然后檢驗(yàn)維度是否匹配,否則就報(bào)錯(cuò)) 3.3.4 NA 處理統(tǒng)計(jì)學(xué)意義上缺失變量(值不知道的變量)的值是 NA。這和一個(gè)函數(shù)參數(shù)的 missing 特性(即一個(gè)函數(shù)的參數(shù)沒有提供)不能混淆(見Arguments)。 因?yàn)樵酉蛄康脑乇仨毷且粯拥念愋?,因此NA值有多種類型。有一種情況對用戶非常重要。NA的默認(rèn)類型是 logical,除非強(qiáng)制轉(zhuǎn)換成其它類型,因此缺失值可能會(huì)觸發(fā)邏輯索引而不是數(shù)值索引(細(xì)節(jié)見 Indexing)。 含 NA 的數(shù)值和邏輯計(jì)算通

58、常返回 NA。如果對于NA所有取值運(yùn)算結(jié)果都一樣,那么就返回這個(gè)一樣的值。特別是,F(xiàn)ALSE & NA 結(jié)果是 FALSE, TRUE | NA 結(jié)果是 TRUE。 NA 不等于任何其它值(包括自身);測試一個(gè)對象是否為NA應(yīng)該用 is.na。 但是,在函數(shù) match 里面,NA 可以匹配另外一個(gè) NA 值。 結(jié)果不明確的數(shù)值計(jì)算(如0/0)返回結(jié)果是 NaN。這僅僅發(fā)生在實(shí)數(shù)的 double 類型或者復(fù)數(shù)的虛部中。函數(shù) is.nan 用于檢驗(yàn)一個(gè)對象是否是 NaN,函數(shù) is.na 對 NaN也返回TRUE。 把 NaN 強(qiáng)制轉(zhuǎn)換成邏輯型或整型將返回對應(yīng)類型的 NA,但是強(qiáng)制轉(zhuǎn)換成字符型將返回 "NaN"。NaN 是不可比較的,因此檢驗(yàn)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論