R計算系統的快速入門

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

data後面的數值向量會以此填充進4行3列的矩陣中,而且默認的填充方向是縱向的。同時,dimnames指定了行和列的名字。

比較令人感興趣的是從矩陣中提取感興趣的數值塊,這個過程叫做切片。

 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的強大功能。


要想學好任何編程語言,都離不開這幾個字:多練,興趣,折騰,交流。

發佈了29 篇原創文章 · 獲贊 1 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章