《R語言編程藝術(shù)》是R語言領(lǐng)域公認(rèn)的經(jīng)典著作,由著名計(jì)算機(jī)科學(xué)家兼統(tǒng)計(jì)學(xué)家撰寫,它是一本面向R語言開發(fā)者的純編程類書籍,不需要讀者具備統(tǒng)計(jì)學(xué)基礎(chǔ),從編程角度而非統(tǒng)計(jì)學(xué)角度系統(tǒng)講解了R語言的數(shù)據(jù)結(jié)構(gòu)、編程結(jié)構(gòu)、語法、TCP/IP網(wǎng)絡(luò)編程、并行計(jì)算、代碼調(diào)試、程序性能優(yōu)化、編程技巧以及R語言與其他語言的接口等所有與R編程相關(guān)的知識,幾乎面面俱到。本書的實(shí)用性也非常強(qiáng),44個(gè)精選的擴(kuò)展案例,充分展示了R語言在數(shù)據(jù)處理和統(tǒng)計(jì)分析方面的強(qiáng)大能力。
全書一共16章:第1章介紹了學(xué)習(xí)R語言需要掌握的預(yù)備知識以及它的一些重要數(shù)據(jù)結(jié)構(gòu);第2~6章詳細(xì)講解了R語言的主要數(shù)據(jù)結(jié)構(gòu),包括向量、矩陣、數(shù)組、列表、數(shù)據(jù)框和因子;第7~13章全面講解了R語言的語法,包括編程結(jié)構(gòu)、面向?qū)ο筇匦、?shù)學(xué)運(yùn)算與模擬、輸入與輸出、字符串處理、繪圖,以及R語言的調(diào)試方法。第14~16章講解了R語言編程的高級內(nèi)容,如執(zhí)行速度和性能的提升、R語言與C/C++或Python的混合編程,以及R語言的并行計(jì)算等。
著名計(jì)算機(jī)科學(xué)家兼統(tǒng)計(jì)學(xué)家撰寫,R語言領(lǐng)域公認(rèn)經(jīng)典著作。 從純編程角度系統(tǒng)講解R語言的數(shù)據(jù)結(jié)構(gòu)、編程結(jié)構(gòu)、語法、TCP/IP網(wǎng)絡(luò)編程、并行計(jì)算、代碼調(diào)試、程序性能優(yōu)化、編程技巧以及R語言與其他語言的接口。海報(bào):
致 謝
本書很大程度上得益于很多人的幫助和支持。
首先,也是最重要的,我必須感謝技術(shù)審稿人Hadley Wickham先生,他的成名作是ggplot2和plyr這兩個(gè)包。我曾向No Starch出版社推薦過Hadley,因?yàn)槌诉@兩個(gè)包之外,他開發(fā)的其他包在CRAN(R用戶貢獻(xiàn)的代碼庫)上也備受歡迎,可說是經(jīng)驗(yàn)豐富。正如我期待的那樣,Hadley的很多評論為本書增色不少,尤其是他對某些代碼示例的評論,通常他都這樣開頭:“我在想,如果你這么寫會(huì)怎么樣……”。有時(shí)這些評論會(huì)導(dǎo)致原本只帶有一兩個(gè)版本代碼的例子變得要用兩三種甚至更多種不同方式來實(shí)現(xiàn)編程目的,這樣可以比較不同方法的優(yōu)點(diǎn)和缺點(diǎn),我相信讀者會(huì)因此受到啟發(fā)。
非常感謝Jim Porzak,他是灣區(qū)R用戶小組(Bay Area useR Group, BARUG的聯(lián)合創(chuàng)始人,在我寫這本書時(shí)他曾多次鼓勵(lì)我。說起B(yǎng)ARUG,我必須感謝Jim和另一位聯(lián)合創(chuàng)始人Mike Driscoll,感謝他們創(chuàng)建了這個(gè)充滿活力而又富有啟發(fā)性的論壇。在BARUG,介紹R語言精妙應(yīng)用的演講者們經(jīng)常讓我感覺寫這本書是個(gè)很有價(jià)值的項(xiàng)目。BARUG也得益于Revolution Analytics公司的資助以及該公司員工David Smith和Joe Rickert付出的時(shí)間、精力,以及奇妙的想法。
Jay Emerson和Mike Kane,CRAN上備受贊譽(yù)的bigmemory包的作者,他們通讀了第16章的早期文稿,并給出了極富價(jià)值的評論。
John Chambers(S語言的締造者,而S語言是R語言的前身)和Martin Morgan提供了關(guān)于R內(nèi)核的建議,這對我在第14章討論R的性能問題有很大幫助。
7.8.4節(jié)涉及了一個(gè)在編程社區(qū)很有爭議的主題——全局變量的使用。為了有一個(gè)更廣闊的視角,我征求了幾位專家的意見,特別是R核心小組的成員Thomas Lumley和加州大學(xué)戴維斯分校計(jì)算機(jī)科學(xué)學(xué)院的Sean Davis。當(dāng)然,這并不意味著他們認(rèn)可了我在這一節(jié)的觀點(diǎn),不過他們的評論非常有用。
在本項(xiàng)目的前期,我寫了份非常粗糙的(也是非常不完整的)草稿以供公眾評論,后來Ramon Diaz-Uriarte、Barbara F. La Scala、Jason Liao以及我的老朋友Mike Hannon給了我很有幫助的反饋。我的女兒Laura,一名工科學(xué)生,閱讀了前面部分章節(jié)并給出了一些建議,使得本書得以完善。
我自己的CRAN項(xiàng)目以及與R相關(guān)的研究(有些成為了本書的示例)得益于許多人的建議、反饋和(或)鼓勵(lì),特別是Mark Bravington、Stephen Eglen、Dirk Eddelbuett、Jay Emerson、Mike Kane、Gary King、Duncan Murdoch和Joe Rickert。
R核心小組成員Duncan Temple Lang和我在同一個(gè)機(jī)構(gòu)——加州大學(xué)戴維斯分校(UCD)。盡管我們在不同的系,以前也沒有太多接觸,但是這本書也得益于他在這個(gè)校園。他幫助UCD創(chuàng)造了一種廣泛認(rèn)可R的文化氛圍,這讓我能夠很容易地向系里證明我用大量的時(shí)間寫這本書是有價(jià)值的。
這本書是我跟No Starch出版社合作的第二個(gè)項(xiàng)目。當(dāng)我決定寫這本書的時(shí)候,很自然地想到去找No Starch出版社,因?yàn)槲蚁矚g他們產(chǎn)品的這種不拘形式的風(fēng)格、高度實(shí)用性和可接受的價(jià)格。感謝Bill Pollock同意這個(gè)項(xiàng)目,感謝編輯人員Keith Fancher和Alison Law以及自由編輯Marilyn Smith。
最后,但非常重要的是,我要感謝兩位美麗、聰明、有趣的女人——我的妻子Gamis和前面提到的Laura,每次她們問我為什么如此埋頭工作,我說“我正在寫這本R書”,她們都會(huì)欣然接受。
Norman Matloff,著名計(jì)算機(jī)科學(xué)家兼統(tǒng)計(jì)學(xué)家,美國加州大學(xué)戴維斯分校計(jì)算機(jī)科學(xué)系教授,曾是該校統(tǒng)計(jì)專業(yè)的創(chuàng)建者之一,并擔(dān)任過統(tǒng)計(jì)學(xué)教授,對并行編程、網(wǎng)絡(luò)流量、數(shù)據(jù)挖掘、磁盤系統(tǒng)性能等方面的技術(shù)都有深入的研究。他樂于分享,撰寫了多部廣受歡迎的關(guān)于軟件開發(fā)的在線教程,多次為《紐約時(shí)報(bào)》、《華盛頓郵報(bào)》、《福布斯雜志》以及《洛杉磯時(shí)報(bào)》撰寫文章,是《The Art of Debugging》的作者之一。
譯者序
前 言
致 謝
第1章 快速入門
1.1 怎樣運(yùn)行R
1.1.1 交互模式
1.1.2 批處理模式
1.2 第一個(gè)R會(huì)話
1.3 函數(shù)入門
1.3.1 變量的作用域
1.3.2 默認(rèn)參數(shù)
1.4 R語言中一些重要的數(shù)據(jù)結(jié)構(gòu)
1.4.1 向量,R語言中的戰(zhàn)斗機(jī)
1.4.2 字符串
1.4.3 矩陣
1.4.4 列表
1.4.5 數(shù)據(jù)框
1.4.6 類
1.5 擴(kuò)展案例:考試成績的回歸分析
1.6 啟動(dòng)和關(guān)閉R
1.7 獲取幫助
1.7.1 help()函數(shù)
1.7.2 example()函數(shù)
1.7.3 如果你不太清楚要查找什么
1.7.4 其他主題的幫助
1.7.5 批處理模式的幫助
1.7.6 互聯(lián)網(wǎng)資源
第2章 向量
2.1 標(biāo)量、向量、數(shù)組與矩陣
2.1.1 添加或刪除向量元素
2.1.2 獲取向量長度
2.1.3 作為向量的矩陣和數(shù)組
2.2 聲明
2.3 循環(huán)補(bǔ)齊
2.4 常用的向量運(yùn)算
2.4.1 向量運(yùn)算和邏輯運(yùn)算
2.4.2 向量索引
2.4.3 用:運(yùn)算符創(chuàng)建向量
2.4.4 使用seq()創(chuàng)建向量
2.4.5 使用rep()重復(fù)向量常數(shù)
2.5 使用all()和any()
2.5.1 擴(kuò)展案例:尋找連續(xù)出現(xiàn)1的游程
2.5.2 擴(kuò)展案例:預(yù)測離散值時(shí)間序列
2.6 向量化運(yùn)算符
2.6.1 向量輸入,向量輸出
2.6.2 向量輸入,矩陣輸出
2.7 NA與NULL值
2.7.1 NA的使用
2.7.2 NULL的使用
2.8 篩選
2.8.1 生成篩選索引
2.8.2 使用subset()函數(shù)篩選
2.8.3 選擇函數(shù)which()
2.9 向量化的ifelse()函數(shù)
2.9.1 擴(kuò)展案例:度量相關(guān)性
2.9.2 擴(kuò)展案例:對鮑魚數(shù)據(jù)集重新編碼
2.10 測試向量相等
2.11 向量元素的名稱
2.12 關(guān)于c()的更多內(nèi)容
第3章 矩陣和數(shù)組
3.1 創(chuàng)建矩陣
3.2 一般矩陣運(yùn)算
3.2.1 線性代數(shù)運(yùn)算
3.2.2 矩陣索引
3.2.3 擴(kuò)展案例:圖像操作
3.2.4 矩陣元素篩選
3.2.5 擴(kuò)展案例:生成協(xié)方差矩陣
3.3 對矩陣的行和列調(diào)用函數(shù)
3.3.1 使用apply()函數(shù)
3.3.2 擴(kuò)展案例:尋找異常值
3.4 增加或刪除矩陣的行或列
3.4.1 改變矩陣的大小
3.4.2 擴(kuò)展案例:找到圖中距離最近的一對端點(diǎn)
3.5 向量與矩陣的差異
3.6 避免意外降維
3.7 矩陣的行和列的命名問題
3.8 高維數(shù)組
第4章 列表
4.1 創(chuàng)建列表
4.2 列表的常規(guī)操作
4.2.1 列表索引
4.2.2 增加或刪除列表元素
4.2.3 獲取列表長度
4.2.4 擴(kuò)展案例:文本詞匯索引
4.3 訪問列表元素和值
4.4 在列表上使用apply系列函數(shù)
4.4.1 lapply()和sapply()的使用
4.4.2 擴(kuò)展案例:文本詞匯索引(續(xù))
4.4.3 擴(kuò)展案例:鮑魚數(shù)據(jù)
4.5 遞歸型列表
第5章 數(shù)據(jù)框
5.1 創(chuàng)建數(shù)據(jù)框
5.1.1 訪問數(shù)據(jù)框
5.1.2 擴(kuò)展案例:考試成績的回歸分析(續(xù))
5.2 其他矩陣式操作
5.2.1 提取子數(shù)據(jù)框
5.2.2 缺失值的處理
5.2.3 使用rbind()和cbind()等函數(shù)
5.2.4 使用apply()
5.2.5 擴(kuò)展案例:工資研究
5.3 合并數(shù)據(jù)框
5.4 應(yīng)用于數(shù)據(jù)框的函數(shù)
5.4.1 在數(shù)據(jù)框上應(yīng)用lapply()和sapply()函數(shù)
5.4.2 擴(kuò)展案例:應(yīng)用Logistic模型
5.4.3 擴(kuò)展案例:學(xué)習(xí)中文方言的輔助工具
第6章 因子和表
6.1 因子與水平
6.2 因子的常用函數(shù)
6.2.1 tapply函數(shù)
6.2.2 split()函數(shù)
6.2.3 by()函數(shù)
6.3 表的操作
6.3.1 表中有關(guān)矩陣和類似數(shù)組的操作
6.3.2 擴(kuò)展案例: 提取子表
6.3.3 擴(kuò)展案例:在表中尋找頻數(shù)最大的單元格
6.4 其他與因子和表有關(guān)的函數(shù)
6.4.1 aggregate()函數(shù)
6.4.2 cut()函數(shù)
第7章 R語言編程結(jié)構(gòu)
7.1 控制語句
7.1.1 循環(huán)
7.1.2 對非向量集合的循環(huán)
7.1.3 if-else結(jié)構(gòu)
7.2 算術(shù)和邏輯運(yùn)算符及數(shù)值
7.3 參數(shù)的默認(rèn)值
7.4 返回值
7.4.1 決定是否顯式調(diào)用return ()
7.4.2 返回復(fù)雜對象
7.5 函數(shù)都是對象
7.6 環(huán)境和變量作用域的問題
7.6.1 頂層環(huán)境
7.6.2 變量作用域的層次
7.6.3 關(guān)于ls()的進(jìn)一步討論
7.6.4 函數(shù)(幾乎)沒有副作用
7.6.5 擴(kuò)展案例:顯示調(diào)用框的函數(shù)
7.7 R語言中沒有指針
7.8 向上級層次進(jìn)行寫操作
7.8.1 利用超賦值運(yùn)算符對非局部變量進(jìn)行寫操作
7.8.2 用assign()函數(shù)對非局部變量進(jìn)行寫操作
7.8.3 擴(kuò)展案例:用R語言實(shí)現(xiàn)離散事件仿真
7.8.4 什么時(shí)候使用全局變量
7.8.5 閉包
7.9 遞歸
7.9.1 Quicksort的具體實(shí)現(xiàn)
7.9.2 拓展舉例:二叉查找樹
7.10 置換函數(shù)
7.10.1 什么是置換函數(shù)
7.10.2 擴(kuò)展案例:可記錄元素修改次數(shù)的向量類
7.11 寫函數(shù)代碼的工具
7.11.1 文本編輯器和集成開發(fā)環(huán)境
7.11.2 edit()函數(shù)
7.12 創(chuàng)建自己的二元運(yùn)算符
7.13 匿名函數(shù)
第8章 數(shù)學(xué)運(yùn)算與模擬
8.1 數(shù)學(xué)函數(shù)
8.1.1 擴(kuò)展例子:計(jì)算概率
8.1.2 累積和與累積乘積
8.1.3 最小值和最大值
8.1.4 微積分
8.2 統(tǒng)計(jì)分布函數(shù)
8.3 排序
8.4 向量和矩陣的線性代數(shù)運(yùn)算
8.4.1 擴(kuò)展示例:向量叉積
8.4.2 擴(kuò)展示例:確定馬爾科夫鏈的平穩(wěn)分布
8.5 集合運(yùn)算
8.6 用R做模擬
8.6.1 內(nèi)置的隨機(jī)變量發(fā)生器
8.6.2 重復(fù)運(yùn)行時(shí)獲得相同的隨機(jī)數(shù)流
8.6.3 擴(kuò)展案例:組合的模擬
第9章 面向?qū)ο蟮木幊?br />9.1 S3類
9.1.1 S3泛型函數(shù)
9.1.2 實(shí)例:線性模型函數(shù)lm()中的OOP
9.1.3 尋找泛型函數(shù)的實(shí)現(xiàn)方法
9.1.4 編寫S3類
9.1.5 使用繼承
9.1.6 擴(kuò)展示例:用于存儲(chǔ)上三角矩陣的類
9.1.7 擴(kuò)展示例:多項(xiàng)式回歸程序
9.2 S4類
9.2.1 編寫S4類
9.2.2 在S4類上實(shí)現(xiàn)泛型函數(shù)
9.3 S3類和S4類的對比
9.4 對象的管理
9.4.1 用ls()函數(shù)列出所有對象
9.4.2 用rm()函數(shù)刪除特定對象
9.4.3 用save()函數(shù)保存對象集合
9.4.4 查看對象內(nèi)部結(jié)構(gòu)
9.4.5 exists()函數(shù)
第10章 輸入與輸出
10.1 連接鍵盤與顯示器
10.1.1 使用scan()函數(shù)
10.1.2 使用readline()函數(shù)
10.1.3 輸出到顯示器
10.2 讀寫文件
10.2.1 從文件中讀取數(shù)據(jù)框或矩陣
10.2.2 讀取文本文件
10.2.3 連接的介紹
10.2.4 擴(kuò)展案例:讀取PUMS普查數(shù)據(jù)
10.2.5 通過URL在遠(yuǎn)程計(jì)算機(jī)上訪問文件
10.2.6 寫文件
10.2.7 獲取文件和目錄信息
10.2.8 擴(kuò)展案例:多個(gè)文件內(nèi)容的和
10.3 訪問互聯(lián)網(wǎng)
10.3.1 TCP/IP概述
10.3.2 R中的socket
10.3.3 擴(kuò)展案例:實(shí)現(xiàn)R的并行計(jì)算
第11章 字符串操作
11.1 字符串操作函數(shù)概述
11.1.1 grep()
11.1.2 nchar()
11.1.3 paste()
11.1.4 sprintf()
11.1.5 substr()
11.1.6 strsplit()
11.1.7 regexpr()
11.1.8 gregexpr()
11.2 正則表達(dá)式
11.2.1 擴(kuò)展案例:檢測文件名的后綴
11.2.2 擴(kuò)展案例:生成文件名
11.3 在調(diào)試工具edtdbg中使用字符串工具
第12章 繪圖
12.1 創(chuàng)建圖形
12.1.1 基礎(chǔ)圖形系統(tǒng)的核心:plot()函數(shù)
12.1.2 添加線條:abline()函數(shù)
12.1.3 在保持現(xiàn)有圖形的基礎(chǔ)上新增一個(gè)繪圖窗口
12.1.4 擴(kuò)展案例:在一張圖中繪制兩條密度曲線
12.1.5 擴(kuò)展案例:進(jìn)一步考察多項(xiàng)式回歸
12.1.6 添加點(diǎn):points()函數(shù)
12.1.7 添加圖例:legend()函數(shù)
12.1.8 添加文字:text()函數(shù)
12.1.9 精確定位:locator()函數(shù)
12.1.10 保存圖形
12.2 定制圖形
12.2.1 改變字符大小:cex選項(xiàng)
12.2.2 改變坐標(biāo)軸的范圍:xlim和ylim選項(xiàng)
12.2.3 添加多邊形:polygon()函數(shù)
12.2.4 平滑散點(diǎn):lowess()和loess()函數(shù)
12.2.5 繪制具有顯式表達(dá)式的函數(shù)
12.2.6 擴(kuò)展案例:放大曲線的一部分
12.3 將圖形保存到文件
12.3.1 R圖形設(shè)備
12.3.2 保存已顯示的圖形
12.3.3 關(guān)閉R圖形設(shè)備
12.4 創(chuàng)建三維圖形
第13章 調(diào)試
13.1 調(diào)試的基本原則
13.1.1 調(diào)試的本質(zhì):確認(rèn)原則
13.1.2 從小處著手
13.1.3 模塊化的、自頂向下的調(diào)試風(fēng)格
13.1.4 反漏洞
13.2 為什么要使用調(diào)試工具
13.3 使用R的調(diào)試工具
13.3.1 利用debug()和browser()函數(shù)進(jìn)行逐步調(diào)試
13.3.2 使用瀏覽器命令
13.3.3 設(shè)置斷點(diǎn)
13.3.4 使用trace()函數(shù)進(jìn)行追蹤
13.3.5 使用traceback()和debugger()函數(shù)對崩潰的程序進(jìn)行檢查
13.3.6 擴(kuò)展案例:兩個(gè)完整的調(diào)試會(huì)話
13.4 更方便的調(diào)試工具
13.5 在調(diào)試模擬數(shù)據(jù)的代碼時(shí)請確保一致性
13.6 語法和運(yùn)行時(shí)錯(cuò)誤
13.7 在R上運(yùn)行GDB
第14章 性能提升:速度和內(nèi)存
14.1 編寫快速的R代碼
14.2 可怕的for循環(huán)
14.2.1 用向量化提升速度
14.2.2 擴(kuò)展案例:在蒙特卡羅模擬中獲得更快的速度
14.2.3 擴(kuò)展案例:生成冪次矩陣
14.3 函數(shù)式編程和內(nèi)存問題
14.3.1 向量賦值問題
14.3.2 改變時(shí)拷貝
14.3.3 擴(kuò)展案例:避免內(nèi)存拷貝
14.4 利用Rprof()來尋找代碼的瓶頸
14.4.1 利用Rprof()來進(jìn)行監(jiān)視
14.4.2 Rprof()的工作原理
14.5 字節(jié)碼編譯
14.6 內(nèi)存無法裝下數(shù)據(jù)怎么辦
14.6.1 分塊
14.6.2 利用R軟件包來進(jìn)行內(nèi)存管理
第15章 R與其他語言的接口
15.1 編寫能被R調(diào)用的C/C++函數(shù)
15.1.1 R與C/C++交互的預(yù)備知識
15.1.2 例子:提取方陣的次對角線元素
15.1.3 編譯和運(yùn)行程序
15.1.4 調(diào)試R/C程序
15.1.5 擴(kuò)展案例:預(yù)測離散取值的時(shí)間序列
15.2 從Python調(diào)用R
15.2.1 安裝RPy
15.2.2 RPy語法
第16章 R語言并行計(jì)算
16.1 共同外鏈問題
16.2 snow包簡介
16.2.1 運(yùn)行snow代碼
16.2.2 分析snow代碼
16.2.3 可以獲得多少倍的加速
16.2.4 擴(kuò)展案例:K均值聚類
16.3 借助于C
16.3.1 利用多核機(jī)器
16.3.2 擴(kuò)展案例:利用OpenMP解決共同外鏈問題
16.3.3 運(yùn)行OpenMP代碼
16.3.4 OpenMP代碼分析
16.3.5 其他OpenMP指令
16.3.6 GPU編程
16.4 普遍的性能考慮
16.4.1 開銷的來源
16.4.2 簡單并行程序,以及那些不簡單的
16.4.3 靜態(tài)和動(dòng)態(tài)任務(wù)分配
16.4.4 軟件煉金術(shù):將一般的問題轉(zhuǎn)化為簡單并行問題
16.5 調(diào)試R語言并行計(jì)算的代碼
附錄A 安裝R
附錄B 安裝和使用包