R簡介
基於R體系下的Bioconductor項目爲用戶提供了整體解決方案。
R的編程比較簡單。不像Java、C等那麼難學。但靈活性太強了,有時候反而覺得不易掌握。R最強大的地方就是它的統計計算功能,這可以從數據結構和算法兩方面來說。
首先,它的許多數據結構都是爲數據處理的需要而設計的。例如其中有一個叫做data.frame的數據類型,它本質上就是一張二維表,每一行是一條記錄,每一列是一個字段(按統計學的術語來說,每一行是一個觀測,每一列是一個變量)。data.frame是一種類矩陣結構,可以對行和列進行一系列的操作,但它又允許每一列的數據是不同的類型,這跟現實中的很多數據是相符的。當然,其它各種流行的語言要實現這些操作都不是難事,只不過R語言是把這些數據結構作爲內置的一部分。
此外,R語言的絕大多數操作都是向量化的,這和Matlab很像,因此省去了很多顯式的循環。例如,如果x是一個向量,那麼我要將它標準化(減去均值,再除以標準差)就只需要 (x - mean(x)) / sd(x) 形式上就像是在寫數學公式。
除去基礎的數據結構之外,數據處理最重要的一點就是各種統計方法,在這一點上R語言可以不太謙虛地說是無言能及。
R語言的統計方法更新很快,目前已經有3000多個附加軟件包,其中大多數都是統計學專業的老師和學生,以及數據分析人員貢獻的。當然這有好處也有壞處,好處是你永遠可以找到最新的統計方法,因爲那些大牛們發paper時基本上都會將程序編好然後掛到網站上。
推薦一個R的IDE工具:RStudio。下載地址:http://www.rstudio.com/. 不管怎麼說,肯定比R自帶的那個編輯器要強嘍。
Nicklaus Wirth——Pascal之父,曾經因爲一句話“算法+數據結構=程序”,獲得圖靈獎。
所以,有必要詳細地介紹R的數據結構,特別是那些獨特的數據結構,它們給數據處理帶來了很大的便利。
數據結構
向量
向量是R內置的最基本的數據結構, 相當於其它編程語言的數組.那麼如何從頭建立一個向量呢?
v <- c(2, 3, 2, 2, 1) v[1] 2 3 2 2 1
從回顯中可以看到,c函數將一串以逗號分隔的整數存進了一個名爲v的向量裏。c函數(英文:concatenate)的目的是將一串數連接起來。其中[1]表示行數,當內容太多的時候,R會自動換行。
w - 1:10; w [1] 1 2 3 4 5 6 7 8 9 10圍繞向量這一數據結構,有一些內建的方法特別有用。例如查詢一個向量的長度,
length(w); [1] 10再如設置向量的元素的名字,
names(v) <- c("a","b","c","d","e") > names(v) [1] "a" "b" "c" "d" "e"設置名字有什麼用呢?
比如想取一個向量的特定的元素,可以這麼取
names(v) [1] "a" "b" "c" "d" "e" > v["b"]實際上,對於簡單的向量,可以直接根據索引取值。
> v[2] b 3實際上,可以在建立向量的同時設置列名。
> n <- c(a = 1, b = 2, c = 3); > n a b c 1 2 3建立好的向量還可以修改。
> v["a"] <- 100; > v a b c d e 100 3 2 2 1修改的方式並不限於單個值。可以從向量中取出一部分內容構建新的向量。
> v[-1] b c d e 3 2 2 1這裏,可以看出使用-1的索引,實際上是把第一列排除了。相似的用法也可以在Perl裏找到影子,但是意義完全不同,請注意區分。
更復雜點,去除兩個值,結果是b和d兩列被去除了。
> v[-c(2, 4)] a c e 100 2 1這裏,使用了更高級的技巧,v>2返回相同長度的只包含TRUE或FALSE的向量。
> v[v>2] a b 100 3這等價於下面的用法。
> v[which(v > 2)] a b 100 3
如果向量的長度不夠,可以擴充。
> length(v) <- 11 > v a b c d e 100 3 2 2 1 NA NA NA NA NA NA
我們可以看到長度擴大到11,最後面六個值爲NA,相當於JAVA裏的Null。
因子
雖然初學者很少使用到因子類型,但是適當的瞭解可以爲以後打下基礎。因子的特點是用於分類數據,而且不同水平間不重複。
建立一個因子的方法:
> a <- factor(c("low", "low", "low", "high", "high"), levels = c("low", "medium", "high")) > a [1] low low low high high Levels: low medium high訪問一個因子的水平:
> levels(a) [1] "low" "medium" "high"
列表
列表在功能上和JAVA和Perl裏的哈希類似。特別是函數的返回值較多時,可以用列表打包,從而返回一個唯一值。列表中的值可以是異質性的,但次序是固定的。
建立一個列表的方法:
l <- list(1,2,3,4,5) > l [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 [[4]] [1] 4 [[5]] [1] 5更進一步,建立一個命名列表的方法:
info <-list(name="jerry",threedimension=c(40,60,90),salary=2000) info $name [1] "jerry" $threedimension [1] 40 60 90 $salary [1] 2000要想從一個列表中取出特定的值,需要使用索引或名稱:
l[1] [[1]] [1] 1 > info["name"] $name [1] "jerry" > class(info["name"]) [1] "list"實際上,這種方法得到的還是一個列表,只不過只包含一個值。class函數可以得出類型,這裏是list類型。
通過$符號可以得到向量形式的值。
info$salary [1] 2000 > class(info$name) [1] "character"可以從class函數返回的值看出得到的一個字符串向量。
使用unlist函數可以得到將列表轉換成向量形式。
unlist(info) name threedimension1 threedimension2 threedimension3 salary "jerry" "40" "60" "90" "2000"
矩陣
可以想象的出,矩陣是用來存儲數據的。可以將矩陣看成特殊的向量。
從頭建立一個矩陣的方法:
m <- matrix(data=1:12,nrow=4,ncol=3, dimnames=list(c("r1","r2","r3","r4"), c("c1","c2","c3"))) > m c1 c2 c3 r1 1 5 9 r2 2 6 10 r3 3 7 11 r4 4 8 12
比較令人感興趣的是從矩陣中提取感興趣的數值塊,這個過程叫做切片。
m[1,] #抽取矩陣的第一行,學過Mathlab的童鞋應該不陌生 c1 c2 c3 1 5 9 > m[,1] #抽取矩陣的第一列 r1 r2 r3 r4 1 2 3 4 > m[1:2,1:2] #同時抽取行和列 c1 c2 r1 1 5 r2 2 6抽取矩陣的行或列的名稱:
rownames(m) [1] "r1" "r2" "r3" "r4" > colnames(m) [1] "c1" "c2" "c3" > colnames(m)[2] #只抽取第二列的名稱 [1] "c2"
數據框
數據框差不多是最有用的數據結構了。從外部輸入的數據都是以數據框的形式存儲的。數據框類似於矩陣,但是能用於存儲異質性的數據。
從頭建立一個數據框的方法:
Expression<-data.frame(sample1=c(.8,.4,.2), sample2=c(.2,.1,.2),sample3=c(.2,.3,.1)); > Expression sample1 sample2 sample3 1 0.8 0.2 0.2 2 0.4 0.1 0.3 3 0.2 0.2 0.1這裏,直接對數據框的列進行了命名。Expression好似一個矩陣,因爲沒有字符數據,所以它可以很容易地轉換爲矩陣,這樣可以使用矩陣特異的方法對其進行深入的操作了。
> exp<-as.matrix(Expression) > exp sample1 sample2 sample2.1 [1,] 0.8 0.2 0.2 [2,] 0.4 0.1 0.3 [3,] 0.2 0.2 0.1 > class(exp) [1] "matrix"as.matrix是將任何可轉換爲matrix的對象轉換爲matrix的方法。實際上,還有其它方法可用於類型轉換,例如is.character可以將其它對象轉換爲字符串。
> class(v) [1] "numeric" > class(as.character(v)) [1] "character"童鞋們可以自己試試其它類型轉換的方法,如as.numeric, as.logical, as.data.frame等等。
同樣可以對數據框通過索引或列名讀取部分數據。
> Expression[1:2] sample1 sample2 1 0.8 0.2 2 0.4 0.1 3 0.2 0.2 > class(Expression[1:2]) [1] "data.frame" > Expression$sample1 [1] 0.8 0.4 0.2 > class(Expression$sample1) [1] "numeric"可以看出,切片操作得到的是數據框,但如果得到的是一維數據的話,會自動轉成向量。
和Matlab類似,R也提供了查詢矩陣或數據框的維度的方法。
> nrow(exp)#查詢矩陣的行數 [1] 3 > nrow(Expression)#查詢數據框的行數 [1] 3 > ncol(exp)#查詢矩陣的列數 [1] 3 > ncol(Expression)#查詢數據框的列數 [1] 3
接下來,會介紹數據的外部導入,之所以在這裏介紹,是因爲導入的數據會以數據框的形式存儲。
df1 <- read.table(header=T, text=' K value K2 0.766 K3 0.857 K4 0.811 K5 0.711 K6 0.614 ') > class(df1) [1] "data.frame"
再如,我們導入一個數值數據,最後將它轉換爲矩陣。
df2 <- read.table(header=T, text=' Sample1 Sample2 0.453 0.766 0.370 0.857 0.199 0.811 0.888 0.711 0.341 0.614 ')rownames(df2)<-c("probe1","probe2","probe3","probe4","probe5")#指定其行名 df2 Sample1 Sample2 probe1 0.453 0.766 probe2 0.370 0.857 probe3 0.199 0.811 probe4 0.888 0.711 probe5 0.341 0.614 class(df2) [1] "data.frame" df3<-as.matrix(df2) > df3<-as.matrix(df2) > df3 Sample1 Sample2 probe1 0.453 0.766 probe2 0.370 0.857 probe3 0.199 0.811 probe4 0.888 0.711 probe5 0.341 0.614 > class(df3) #[1] "matrix"雖然,直接在命令中輸入少量數據看起來很優雅,然而,真實的生物數據的維度普遍較大,使用文件導入的方式較合適。
dat <- read.csv("class_exp1.csv",header= T, row.name= 1)如果目標文件不在當前目錄,可以通過設置當前絕對路徑指定。
setwd("E:/R講解基本/2-練習數據") dat <- read.csv("class_exp1.csv",header= T, row.name= 1) #或者直接指定絕對路徑 dat <- read.csv("E:/R講解基本/2-練習數據/class_exp1.csv",header= T, row.name= 1)小結:在介紹完這些關於常見數據結構的最最基本的內容之後,或許你已經可以磕磕絆絆地進行一些數據分析。然而,更深入的數據分析或許需要更多的練習和技巧,希望大家進一步學習和不斷提高。推薦一本參考書《R Cookbook》。它其實就是一本參考手冊,從中可找到你感興趣的內容。很顯然,你不需要將此書從頭讀到尾,只需要找你需要的內容,copy並修改加入到自己的script裏。然而,你還是需要大致瀏覽此書,以幫助你快速找到想要找到的知識。
此外,R FOR DUMMIES也是爲新手推薦的一本參考書。雖然,該書還沒有中文版出版,但是具備大學英語4級以上的水平的讀者相信閱讀此書都不會有太大障礙。況且,你學習的是此書涉及的代碼,在一定的語境的條件下,對文字的理解會有所幫助。這本書並不追求技巧,而是將讀者的水平置於很低的層次,逐漸地提高,是推薦給新手的可選讀物。
R繪圖快速入門
這裏要介紹的是基於ggplot2包快速繪製高品質圖像。
什麼是ggplot2
ggplot2是用於繪圖的R語言擴展包。它將繪圖視爲一種映射,即從數學空間映射到圖形元素空間。例如將不同的數值映射到不同的色彩或透明度。該繪圖包的特點在於並不去定義具體的圖形(如直方圖,散點圖),而是定義各種底層組件(如線條、方塊)來合成複雜的圖形,這使它能以非常簡潔的函數構建各類圖形,而且默認條件下的繪圖品質就能達到出版要求。
與lattice包的比較
ggplot2和lattice都屬於高級的格點繪圖包,初學R語言的朋友可能會在二者選擇上有所疑惑。從各自特點上來看,lattice入門較容易,作圖速度較快,圖形函數種類較多,比如它可以進行三維繪圖,而ggplot2就不能。ggplot2需要一段時間的學習,但當你跨過這個門檻之後,就能體會到它的簡潔和優雅,而且ggplot2可以通過底層組件構造前所未有的圖形,你所受到的限制只是你的想象力。雖然總體感受是入門慢,但是功能確實強大。這裏我推薦學習ggplot2。基本上,你只需要掌握一個命令即可學會畫圖。畫圖的畫圖命令跟搭積木很類似,大大加快了繪圖效率。特別推薦《R Graphics Cookbook》。其實你完全不懂ggplot2,將它上面的代碼改動一下,完全可以應付大部分的生物信息畢業論文了。
基本概念
圖層(Layer):如果你用過photoshop,那麼對於圖層一定不會陌生。一個圖層好比是一張玻璃紙,包含有各種圖形元素,你可以分別建立圖層然後疊放在一起,組合成圖形的最終效果。圖層可以允許用戶一步步的構建圖形,方便單獨對圖層進行修改、增加統計量、甚至改動數據。
標度(Scale):標度是一種函數,它控制了數學空間到圖形元素空間的映射。一組連續數據可以映射到X軸座標,也可以映射到一組連續的漸變色彩。一組分類數據可以映射成爲不同的形狀,也可以映射成爲不同的大小。
座標系統(Coordinate):座標系統控制了圖形的座標軸並影響所有圖形元素,最常用的是直角座標軸,座標軸可以進行變換以滿足不同的需要,如對數座標。其它可選的還有極座標軸。
位面(Facet):很多時候需要將數據按某種方法分組,分別進行繪圖。位面就是控制分組繪圖的方法和排列形式。
ggplot2的安裝
在第一次使用ggplot2之前,你需要安裝它。
install.packages("ggplot2")在每次使用ggplot2之前,你需要將它導入到R環境。
library(ggplot2)
ggplot2的例子
接下來,我們將使用R內置的一個數據,演示ggplot2的強大能力,開始發揮你的創造力吧。
data(mtcars)mtcars這套數據是記錄汽車性能和部件的關係。這裏,我們先看看Drat: Rear axle ratio(後軸比) 和wt: Weight(容量)之間的關係。由於該數據較大,我們先顯示前兩行,相信你沒忘了這些基本的切片操作的命令(O(∩_∩)O~~)。
> mtcars[1:2,] mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 21 6 160 110 3.9 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4先使用一個最基本的命令,直觀地看看效果。
ggplot(mtcars,aes(x=drat,y=wt))+geom_point()
接着,我們仔細審視這條唯一你需要掌握的命令。
ggplot(mtcars,aes(x=drat,y=wt))+geom_point() | | | 數據框(必需)aes中的每一項將 幾何元件 geom被映射到特定的 可視化元件
給ggplot喂的數據需要是一個數據框。
aes項每個點都有自己圖像上的屬性,比如x座標,y座標,點的大小、顏色和形狀,這些都叫做aesthetics,即圖像上可觀測到的屬性,通過aes函數來賦值
geom決定了圖像的“type”,即幾何特徵,是用點來描述圖像,還是用柱,或者用條形.因此,通過修改geom項,可以修改圖的類型。
我們接着改變一下幾何元件,看看效果。
ggplot(mtcars,aes(x=drat,y=wt,color=as.character(gear)))+geom_smooth()
我們看看將gear作爲數值的情況的效果(這條命令有些古怪,有的時候不能運行,可以考慮最後運行它)。
ggplot(mtcars,aes(x=drat,y=wt,color=gear))+geom_point()
這裏,可以看到點的研究隨着gear的值得變化而變化,你可以試着把gear強制變爲character,再運行一次,比較一下。可以清楚看出這裏還是比較適宜用字符型的gear,因爲gear只有三個值。如果一個變量是連續範圍的,不用強制變爲字符串的類型。
我們再做一些變動,比較一下效果。
ggplot(mtcars,aes(x=drat,y=wt))+geom_point()+geom_smooth()
我們發現幾何元件其實是可以疊加的。這樣不僅可以同時顯示散點,也可以顯示平滑的曲線圖,這種圖被用來顯示置信區間。
接下來,我們只對一個變量進行繪圖。
ggplot(mtcars,aes(x=drat))+geom_density()
我們發現顯示的是drat這個變量的值的分佈。
爲了考察在另一個變量gear不同(3,4,5)的情況下,drat的分佈,我們進一步加了點東西。
ggplot(mtcars,aes(x=drat))+geom_density()+facet_grid(~gear)
facet_grid方法的確很神奇,可以按照傳遞給它的變量的值分成不同的情況。需要注意的是gear前面的~。
最後,照例給大家推薦一本ggplots的工具書:R Graphics Cookbook。這本書大部分的例子都是用ggplot2實現的,可見ggplot2的強大功能。
要想學好任何編程語言,都離不開這幾個字:多練,興趣,折騰,交流。