【生信技能樹培訓(xùn)】R語(yǔ)言基礎(chǔ)【20230112更新】

本培訓(xùn)使用R 4.2及以上版本。

一、前言

用R分析數(shù)據(jù)得出結(jié)果,需要解決兩個(gè)問題:

用什么包/函數(shù)來處理數(shù)據(jù)?
如何整理數(shù)據(jù),使得數(shù)據(jù)可以套進(jìn)函數(shù)里進(jìn)行處理?

(一)在R中新建項(xiàng)目

方式:RStudio中,菜單欄File→NewProject→NewDirectory→NewProject→DirectoryName

該方式通過新建一個(gè)目錄的方式來新建一個(gè)項(xiàng)目,創(chuàng)建一個(gè)R的項(xiàng)目文件(Rproj):

  • 將所有與該項(xiàng)目相關(guān)的數(shù)據(jù)、腳本、文件等都存放在該項(xiàng)目文件夾下,每次通過運(yùn)行Rproj文件啟動(dòng)項(xiàng)目,自動(dòng)關(guān)聯(lián)相關(guān)文件,便于統(tǒng)一管理和調(diào)試。
  • 該項(xiàng)目的工作目錄即為新建該項(xiàng)目創(chuàng)建的目錄。即后續(xù)創(chuàng)建的腳本文件默認(rèn)保存位置均為該目錄。
  • 項(xiàng)目目錄移動(dòng)后,項(xiàng)目中的文件、腳本仍然可以通過項(xiàng)目文件(Rproj)關(guān)聯(lián)使用。

(二)在項(xiàng)目中新建腳本

方式:Rstudio菜單欄,F(xiàn)ile→NewFile→RScript

保存:

  • R腳本保存的文件后綴為.R
  • 保存的默認(rèn)位置為當(dāng)前的工作目錄(working directory)

Tips:
腳本中點(diǎn)擊Run或快捷鍵ctrl+Enter,執(zhí)行光標(biāo)所在行的代碼,光標(biāo)會(huì)移動(dòng)到下一行
腳本中選中多行,點(diǎn)擊Run,執(zhí)行所選的代碼
使用#為腳本添加注釋。讓自己和其他協(xié)作者了解代碼的用途。R不會(huì)執(zhí)行#后面的內(nèi)容。

(三)與R交互的兩種方式

1. 控制臺(tái)窗口(console)

顯示每個(gè)命令的結(jié)果

2. 腳本編輯器

記錄工作代碼,讓代碼和工作流程具有可重復(fù)性。

點(diǎn)擊Run來運(yùn)行代碼

(四)程序運(yùn)行的問題指南

1. 出現(xiàn)ERROR

即報(bào)錯(cuò)。需要對(duì)癥處理。

2. 長(zhǎng)時(shí)間運(yùn)行中,并未出現(xiàn)命令提示符>

可能卡住了。點(diǎn)擊console窗口右上角紅色STOP按鈕終止程序運(yùn)行。

3. 運(yùn)行出結(jié)果、沒反應(yīng)、出現(xiàn)warning、其他提示信息,出現(xiàn)新一行的命令提示符>

目前一切順利

4. 出現(xiàn)問題

必須回答。

5. 出現(xiàn)+

代碼不完整。補(bǔ)齊代碼,或按ESC鍵退出。

二、數(shù)據(jù)類型

  • 數(shù)值型(numeric)
    1.3 2
  • 字符型(character)
    “a” “nn”
  • 邏輯型(logical)
    TRUE(T) FALSE(F) NA
    NA:為缺失值,表示存在但未知。
    NULL:為空,表示沒有這個(gè)值(不存在)。

可以用函數(shù)class()來判斷數(shù)據(jù)的類型。

Tips:打出前幾個(gè)字母即出現(xiàn)提示,用上下鍵翻動(dòng),Tab鍵自動(dòng)補(bǔ)全

(一)邏輯型數(shù)據(jù)

比較運(yùn)算

比較運(yùn)算的結(jié)果是邏輯值。

比較運(yùn)算符號(hào):

<,>, >=, <=, ==(判斷是否相等), !=(判斷是否不等)

舉例:

> 3==5
[1] FALSE
> 3!=5
[1] TRUE

多個(gè)邏輯條件的連接

連接符號(hào):

& 表示和/與

| 表示或

!表示非

舉例:

> 3<5&4>5
[1] FALSE
> 3<5 | 4>5
[1] TRUE
> !(4>5)
[1] TRUE

(二)數(shù)據(jù)類型的判斷和轉(zhuǎn)換

is族函數(shù),判斷數(shù)據(jù)類型,返回值為邏輯值

is.numeric()
是否為數(shù)值型數(shù)據(jù)
is.logical()
是否為邏輯型數(shù)據(jù)is.character()
是否為字符型數(shù)據(jù)

as族函數(shù)實(shí)現(xiàn)數(shù)據(jù)類型之間的轉(zhuǎn)換

as.numeric()
將其他數(shù)據(jù)類型轉(zhuǎn)換為數(shù)值型
as.logical()
將其他數(shù)據(jù)類型轉(zhuǎn)換為邏輯型as.character()
將其他數(shù)據(jù)類型轉(zhuǎn)換為字符型

本節(jié)函數(shù)

1. class()

描述:判斷數(shù)據(jù)類型。

舉例:

> class(2)
[1] "numeric"
> class('abc')
[1] "character"
> class(FALSE)
[1] "logical"
> class(NA)
[1] "logical"

2. is.numeric()

描述:判斷是否為數(shù)值型數(shù)據(jù)

舉例:

> is.numeric("a")
[1] FALSE
> is.numeric("4")
[1] FALSE

3. is.logical()

描述:判斷是否為邏輯型數(shù)據(jù)

舉例:

> is.logical(FALSE)
[1] TRUE

4. is.character()

描述:判斷是否為字符型數(shù)據(jù)

舉例:

> is.character("4")
[1] TRUE

5. as.numeric()

描述:將其他數(shù)據(jù)類型轉(zhuǎn)換為數(shù)值型

舉例:

> as.numeric('4')
[1] 4
> as.numeric('jimmy')
[1] NA
Warning message:
NAs introduced by coercion 

討論:開始講,NA表示“存在但未知”,as.numeric("jimmy")返回NA,意思是可以將Jimmy這個(gè)字符串轉(zhuǎn)換成數(shù)值類型,但是這個(gè)這個(gè)值是未知的?R轉(zhuǎn)換了類型,但不知道是個(gè)啥,所以返回了NA。NA也有數(shù)值型NA和字符型NA。
參見以下代碼:

> a <- 'jimmy'
> class(a)
[1] "character"
> a <- as.numeric(a)
Warning message:
NAs introduced by coercion 
> class(a)
[1] "numeric"

6. as.logical()

描述:將其他數(shù)據(jù)類型轉(zhuǎn)換為邏輯型

舉例:

> as.logical(4)
[1] TRUE
> as.logical('a')
[1] NA

7. as.character()

描述:將其他數(shù)據(jù)類型轉(zhuǎn)換為字符型

舉例:

> as.character(4)
[1] "4"
> as.character(TRUE)
[1] "TRUE"

三、數(shù)據(jù)結(jié)構(gòu)

R語(yǔ)言中主要有4種數(shù)據(jù)結(jié)構(gòu),如下:

image.png

- 數(shù)據(jù)框約等于“表格”。數(shù)據(jù)框要求每一列只能有一種數(shù)據(jù)類型,且數(shù)據(jù)框只是R語(yǔ)言內(nèi)部的一個(gè)數(shù)據(jù),不是一個(gè)文件。

- 數(shù)據(jù)框單獨(dú)拿出來的一列是一個(gè)向量,視為一個(gè)整體。一個(gè)向量可以出自數(shù)據(jù)框的一列,也可以用代碼生成。

- 一個(gè)向量只能有一種數(shù)據(jù)類型,可以有重復(fù)值。

Tips:若打開的腳本文件是亂碼,可以將編碼修改成UTF-8來解決(File→Reopen with Encoding→UTF-8)。若還不行,則腳本文件本身可能已經(jīng)損壞。

(一)向量(vector)

向量是一維的。

I.向量的生成

1. 用函數(shù)c()集合在一起生成

舉例:

> c(2,5,6,2,9)
[1] 2 5 6 2 9
> c('a','f','md','b')
[1] "a"  "f"  "md" "b" 
2. 生成連續(xù)的數(shù)字向量用冒號(hào)“:”

舉例:

> 1:5
[1] 1 2 3 4 5
3. 有重復(fù)的用函數(shù)rep(),有規(guī)律的序列用seq(),隨機(jī)數(shù)用rnorm()

舉例:

rep('x',times=3)
[1] "x" "x" "x"
> seq(from=3, to=21, by=3)
[1]  3  6  9 12 15 18 21
> rnorm(n=3)
[1] -1.7067961  0.6295338 -0.9499346
4. 通過組合,產(chǎn)生更為復(fù)雜的向量

舉例:

> paste0(rep('x',times=3),1:3)
[1] "x1" "x2" "x3"

II.對(duì)單個(gè)向量進(jìn)行的操作

1. 賦值

舉例:

> x <- c(1,3,5,1)  #<-是規(guī)范的賦值符號(hào),快捷鍵Alt+-
> x
[1] 1 3 5 1
> x = c(1,3,5,1) #比較隨意的寫法
> x
[1] 1 3 5 1

賦值和輸出一起實(shí)現(xiàn)

舉例:

> (x <- c(1,3,5,1))
[1] 1 3 5 1
> x <- c(1,3,5,1);x  
[1] 1 3 5 1

變量名稱的選擇:

不建議用函數(shù)或包的名稱。
不建議用帶引號(hào)的字符。
可以用字母和數(shù)字的組合,但是數(shù)字要在字母后面。
不能用空格,運(yùn)算符號(hào)在名稱中??梢允褂孟聞澗€。
不建議用中文作為變量名稱。

2. 計(jì)算
> x <- c(1,3,5,1);x
[1] 1 3 5 1
> x+1
[1] 2 4 6 2
> log(x)
[1] 0.000000 1.098612 1.609438 0.000000
> sqrt(x) #開方運(yùn)算
[1] 1.000000 1.732051 2.236068 1.000000
3. 進(jìn)行比較運(yùn)算,生成邏輯值向量
> x>3
[1] FALSE FALSE  TRUE FALSE
> x==3
[1] FALSE  TRUE FALSE FALSE
4. 初級(jí)的統(tǒng)計(jì)運(yùn)算
> max(x) #最大值
[1] 5
> min(x) #最小值
[1] 1
> mean(x) #均值
[1] 2.5
> median(x) #中位數(shù)
[1] 2
> var(x) #方差
[1] 3.666667
> sd(x) #標(biāo)準(zhǔn)差
[1] 1.914854
> sum(x) #總和
[1] 10

幾個(gè)重要的統(tǒng)計(jì)函數(shù)

> length(x) #長(zhǎng)度,即向量的元素個(gè)數(shù)
[1] 4
> unique(x) #去重復(fù),去除向量中重復(fù)的元素,只保留第一次出現(xiàn)的那個(gè)(從左到右)
[1] 1 3 5
> duplicated(x) #判斷對(duì)應(yīng)元素是否在前面(左邊)出現(xiàn)過重復(fù)。沒出現(xiàn)返回FALSE,出現(xiàn)返回TRUE。所以重復(fù)的元素,第一次出現(xiàn)返回FALSE,后面的重復(fù)都返回TRUE。
[1] FALSE FALSE FALSE  TRUE
> table(x) #重復(fù)值統(tǒng)計(jì)
x
1 3 5  #第一行返回向量中的取值(去重后的向量元素)
2 1 1  #第二行返回每個(gè)元素的重復(fù)次數(shù)
> sort(x)  #默認(rèn)升序排序
[1] 1 1 3 5
> sort(x,decreasing = F) #即默認(rèn)參數(shù)decreasing為FALSE
[1] 1 1 3 5
> sort(x,decreasing = T) #將decreasing改為TRUE,即降序打開,結(jié)果將按照降序排列。
[1] 5 3 1 1

本節(jié)函數(shù)

1. rep()

描述:復(fù)制參數(shù)x的值。

格式:rep(x, ...)

參數(shù):

x 為向量

... 可以為

times,若為1個(gè)元素,則表示重復(fù)x向量的次數(shù);若為長(zhǎng)度與x向量相等的向量,則表示分別重復(fù)x中各元素的次數(shù)。

length.out,指定輸出向量的長(zhǎng)度,從左至右選擇,多余的元素舍棄。

each,指定x中每個(gè)元素重復(fù)的次數(shù)。

舉例:

> rep('x',times=3)
[1] "x" "x" "x"
> rep(1:4, 2)
[1] 1 2 3 4 1 2 3 4
> rep(1:4, each = 2)
[1] 1 1 2 2 3 3 4 4
> rep(1:4, each = 2, length.out = 4)
[1] 1 1 2 2

2. seq()

描述:生成有規(guī)律的序列

格式:seq(from=... , to= ... , by=... )

參數(shù):

from,to 指定序列的起始值和最大結(jié)束值

by 指定序列的增量

也可以有l(wèi)ength.out參數(shù)指定輸出向量的長(zhǎng)度,則by通過指定的長(zhǎng)度計(jì)算得出。

舉例:

> seq(from=3, to=21, by=3)
[1]  3  6  9 12 15 18 21

3. rnorm()

描述:生成指定個(gè)數(shù)的服從正態(tài)分布的隨機(jī)數(shù),可以指定均數(shù)和標(biāo)準(zhǔn)差。

格式:rnorm(n, mean=0, sd=1)

參數(shù):

n 指定生成的隨機(jī)數(shù)的個(gè)數(shù)

mean 指定生成隨機(jī)數(shù)的平均數(shù),默認(rèn)為0

sd 指定生成隨機(jī)數(shù)的標(biāo)準(zhǔn)差,默認(rèn)為1

舉例:

> rnorm(n=3)
[1] -1.7067961  0.6295338 -0.9499346

4. paste0()與paste()

描述:將向量轉(zhuǎn)換成字符型數(shù)據(jù)后進(jìn)行連接。

格式:paste(...,sep=" ",collapse=NULL )

       paste0與paste(..., sep="", cllapse=NULL)相同

參數(shù):

... 可以是1個(gè)或多個(gè)向量,當(dāng)其為1個(gè)向量時(shí),其作用相當(dāng)于函數(shù)as.character()

sep 多個(gè)向量連接時(shí),指定各元素之間的連接符號(hào),paste默認(rèn)為空格,paste0固定為空(即元素之間沒有連接符號(hào),緊密連接)

collapse 非單元素的多向量連接時(shí),將生成的多個(gè)元素合并成1個(gè)元素,并指定多元素間合并的連接符號(hào)

舉例:

> paste0(rep('x',times=3),1:3)
[1] "x1" "x2" "x3"
> paste(rep('x',times=3),1:3, sep=',')
[1] "x,1" "x,2" "x,3"
> paste(rep('x',times=3),1:3, collapse=',')
[1] "x 1,x 2,x 3"
>  paste(rep('x',times=3),1:3, collapse='-')
[1] "x 1-x 2-x 3"

5. log()和sqrt()

描述:取對(duì)數(shù)運(yùn)算和開方運(yùn)算的函數(shù)

舉例:

> x <- c(1,3,5,1)
> log(x)
[1] 0.000000 1.098612 1.609438 0.000000
> sqrt(x) 
[1] 1.000000 1.732051 2.236068 1.000000

6. 另外參見文中統(tǒng)計(jì)函數(shù)部分的函數(shù)介紹

探索

練習(xí)2-2,1.生成1到15之間所有偶數(shù)講解的答案是:

seq(from=2, to=15, by=2)

講解中提到,如果:

seq(from=1, to=15, by=2)

則生成1到15的奇數(shù),與題目的要求不符??梢酝ㄟ^加1變成偶數(shù),再想法去掉多出來的16這個(gè)數(shù)。這種方式比較復(fù)雜。但本著熟悉代碼的原則,我按照這種思路進(jìn)行嘗試,有以下2種方式得出相同的結(jié)果:

seq(1,15,2)c(1:7)+1    #首先取出7個(gè)奇數(shù)再變成偶數(shù)
> 1  2  4  6  8 10 12 14(seq(1,15,2)+1)c(1:7)  #先將8個(gè)奇數(shù)變成偶數(shù),再取出其中7個(gè)
> 1  2  4  6  8 10 12 14

Tips:向量只允許一種數(shù)據(jù)類型存在,當(dāng)出現(xiàn)不同類型的數(shù)據(jù)時(shí),會(huì)自動(dòng)根據(jù)下圖的優(yōu)先順序進(jìn)行轉(zhuǎn)換。

image.png

III.對(duì)兩個(gè)向量的操作

1. 比較運(yùn)算,生成等長(zhǎng)的邏輯向量

> x == y 
[1] FALSE FALSE  TRUE FALSE
> y == x
[1] FALSE FALSE  TRUE FALSE

2. 數(shù)學(xué)計(jì)算

> x + y
[1]  4  5 10  7

3. 連接

> paste(x,y,sep=",")
[1] "1,3" "3,2" "5,5" "1,6"

paste與paste0的區(qū)別見前文“本節(jié)函數(shù)”

循環(huán)補(bǔ)齊

當(dāng)兩個(gè)向量長(zhǎng)度不一致時(shí),會(huì)通過循環(huán)補(bǔ)齊的方式對(duì)照較長(zhǎng)的那個(gè)向量補(bǔ)齊運(yùn)算。

image.png

利用循環(huán)補(bǔ)齊簡(jiǎn)化代碼:

> paste0(rep("x",3),1:3)
[1] "x1" "x2" "x3"
> paste0("x",1:3)
[1] "x1" "x2" "x3"

4. 交集、并集、差集

> x;y
[1] 1 3 5 1
[1] 3 2 5 6
> intersect(x,y)
[1] 3 5
> union(x,y)
[1] 1 3 5 2 6
> setdiff(x,y)  #取差集,x中有而y中沒有的元素,即并集中去掉y,???后文的半連接
[1] 1
> setdiff(y,x)  #取差集,y中有而x中沒有的元素,即并集中去掉x
[1] 2 6

重點(diǎn):%in%

x %in% y  #x的每個(gè)元素在y中是否存在

> x;y
[1] 1 3 5 1
[1] 3 2 5 6
> x %in% y #x的每個(gè)元素在y中存在嗎
[1] FALSE  TRUE  TRUE FALSE
> y %in% x
[1]  TRUE FALSE  TRUE FALSE

%in%返回的邏輯值向量與該符號(hào)前面向量中的每個(gè)元素一一對(duì)應(yīng)。

==與%in%的區(qū)別
image.png

當(dāng)兩個(gè)向量長(zhǎng)度不等時(shí),==會(huì)發(fā)生循環(huán)補(bǔ)齊;而%in%不適用。
==是元素對(duì)應(yīng)位置的比較,有順序的影響,%in%前后兩個(gè)向量中所有元素都會(huì)互相比較,沒有順序的影響。下圖中的問題,則應(yīng)該使用%in%而不能使用==。(即xx %in% y)

image.png
intersect()與%in%的區(qū)別

取交集會(huì)去重復(fù),而%in%取子集不會(huì)。見R_01項(xiàng)目中02_exercise.R練習(xí)第6題。

> # 6.向量g中有多少個(gè)元素在向量s中存在(要求用函數(shù)計(jì)算出具體個(gè)數(shù))?將這些元素篩選出來
#正確答案
> table(g %in% s)

FALSE  TRUE 
   37    63 
> g[g %in% s]
 [1] "GFM2"          "SLCO1C1"       "NYNRIN"        "COMMD1"       
 [5] "COMMD1"        "AC017081.1"    "RAB7A"         "CASKIN2"      
 [9] "GGT7"          "SNRPE"         "RGPD3"         "ZNF586"       
[13] "COMMD1"        "GGT7"          "URB1"          "RAB7A"        
[17] "MPP2"          "AFG3L2"        "URB1"          "AC104581.1"   
[21] "MPP2"          "SNRPE"         "ARHGAP1"       "ZNF461"       
[25] "OR2D3"         "CECR5"         "SPDL1"         "CLEC17A"      
[29] "ZNF461"        "ATG10"         "ATG10"         "ATG10"        
[33] "SLC25A25"      "SLC30A9"       "SLCO1C1"       "GGT7"         
[37] "CASKIN2"       "GSTP1"         "MPP2"          "NYNRIN"       
[41] "INTS12"        "MPP2"          "RGPD3"         "RGPD3"        
[45] "SLC30A9"       "C10orf128"     "HBD"           "SLC30A9"      
[49] "GGT7"          "HEPH"          "RP5-1021I20.4" "KLHDC8A"      
[53] "HBD"           "ZNF586"        "CECR5"         "OR2D3"        
[57] "LIPE"          "INTS12"        "LIPE"          "SPDL1"        
[61] "SLCO1C1"       "GGT7"          "CECR5"   
#錯(cuò)誤使用取交集函數(shù)。
> length(intersect(g,s))
[1] 32

IV.向量篩選(取子集)

用 將TRUE對(duì)應(yīng)的值挑選出來,F(xiàn)ALSE丟棄。

> x <- 8:12
> x
[1]  8  9 10 11 12
 #根據(jù)邏輯值取子集
> x[x==10]
[1] 10
> x[x<12]
[1]  8  9 10 11
> x[x %in% c(9,13)]
[1] 9
 #根據(jù)位置取子集
> x[4]
[1] 11
> x[2:4]
[1]  9 10 11
> x[c(1,5)]
[1]  8 12
> x[-4]    #-表示除了該位置的其他元素都取出來,只支持?jǐn)?shù)字,不支持邏輯值。邏輯值取相反用嘆號(hào)!
[1]  8  9 10 12
> x[-(2:4)]
[1]  8 12

Tips:

-(減號(hào))表示除了該位置的其他元素都取出來,只支持?jǐn)?shù)字,不支持邏輯值。邏輯值取相反用?。▏@號(hào))

重點(diǎn):

按照邏輯值:中括號(hào)里是與x等長(zhǎng)且一一對(duì)應(yīng)的邏輯值向量。
按照位置:中括號(hào)里是由x下標(biāo)組成的向量。
因此,指定向量中的具體某個(gè)元素時(shí),無論用邏輯值還是位置來指定,都必須使用向量。

下面的代碼會(huì)報(bào)錯(cuò):

> x
[1]  8  9 10 11 12
> x==10
[1] FALSE FALSE  TRUE FALSE FALSE
> x[FALSE,FALSE,TRUE,FALSE,FALSE]
Error in x[FALSE, FALSE, TRUE, FALSE, FALSE] : 
  incorrect number of dimensions
> x[3,5]
Error in x[3, 5] : incorrect number of dimensions

報(bào)錯(cuò)中顯示維度錯(cuò)誤。向量是一維的,中括號(hào)中逗號(hào)分割表示多維度,所以報(bào)錯(cuò)。指定多維度的數(shù)據(jù)時(shí),用逗號(hào)分割。

V.修改向量中的某個(gè)(些)元素

1. 改一個(gè)元素

> x
[1]  8  9 10 11 12
> x[4] <- 40
> x
[1]  8  9 10 40 12

2. 改多個(gè)元素

> x
[1]  8  9 10 11 12
> x[c(1,5)] <- c(80,20)
> x
[1] 80  9 10 40 20

注意:修改元素就是取子集+賦值的聯(lián)合操作。

VI.簡(jiǎn)單向量作圖

> k1 = rnorm(12);k1
 [1]  0.04332943 -0.75023874  0.51691113  1.10119324
 [5]  1.59135095 -0.04078699 -0.65780426  0.93452471
 [9]  1.44189919  0.44143937 -0.21297901 -0.25711064
> plot(k1)  #作點(diǎn)圖

> k2 = rep(c("a","b","c","d"),each = 3);k2
 [1] "a" "a" "a" "b" "b" "b" "c" "c" "c" "d" "d" "d"
> boxplot(k1~k2) #作箱線圖。將k1作為y軸;k2作為x軸
image.png

image.png

plot() 默認(rèn)作散點(diǎn)圖,可以指定另外的作圖形式(折線圖,點(diǎn)線圖等,詳見幫助文檔)
boxplot()連接指定需要作圖的數(shù)學(xué)公式中的函數(shù)和自變量(可以是組合分組變量),如:boxplot(yg1:g2)。詳見幫助文檔

(二)矩陣(matrix)

  • 矩陣是二維的。
  • 只允許一種數(shù)據(jù)類型。

Tips: 判斷數(shù)據(jù)結(jié)構(gòu)

  1. 根據(jù)生成他的函數(shù)來判斷
  2. 用函數(shù)class或is族函數(shù)來判斷

I.新建矩陣和取子集

矩陣取子集,不支持$符號(hào)。

#新建矩陣
> m <- matrix(1:9, nrow = 3)
> m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
#加列名
> colnames(m) <- c("a","b","c")
> m
     a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
#取第2行
> m[2,]
a b c     #由于加了列名,所以取出的行,會(huì)帶上對(duì)應(yīng)的列名一起輸出
2 5 8     
#取第1列
> m[,1]
[1] 1 2 3
#取第2行第3列的數(shù)值,同樣會(huì)帶上對(duì)應(yīng)的列名。
> m[2,3]
c 
8 
#取出指定的連續(xù)的行和列。
> m[2:3,1:2]
     a b
[1,] 2 5
[2,] 3 6

II.矩陣的轉(zhuǎn)置和轉(zhuǎn)換

> m
     a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
#轉(zhuǎn)置
> t(m)  #t函數(shù)可以將矩陣或者數(shù)據(jù)框的行和列進(jìn)行互換
  [,1] [,2] [,3]
a    1    2    3
b    4    5    6
c    7    8    9
#轉(zhuǎn)換
> as.data.frame(m)  #將矩陣轉(zhuǎn)換成數(shù)據(jù)框的數(shù)據(jù)結(jié)構(gòu)
  a b c
1 1 4 7
2 2 5 8
3 3 6 9

重點(diǎn):

將數(shù)據(jù)框或舉證轉(zhuǎn)置之后,其數(shù)據(jù)結(jié)構(gòu)都是矩陣。

> df1
    gene CHANGE score p.value
r1 gene1     up    12    0.01
r2 gene2     up    23    0.02
r3 gene3   down    50    0.07
r4 gene4   down     2    0.05
> t(df1)
        r1      r2      r3      r4     
gene    "gene1" "gene2" "gene3" "gene4"
CHANGE  "up"    "up"    "down"  "down" 
score   "12"    "23"    "50"    " 2"   
p.value "0.01"  "0.02"  "0.07"  "0.05" 
> class(t(df1))
[1] "matrix" "array" 

由于矩陣要求所有數(shù)據(jù)類型都相同,因此,轉(zhuǎn)置后的矩陣數(shù)據(jù)都是字符串類型。

若此時(shí)將矩陣轉(zhuǎn)換成數(shù)據(jù)框數(shù)據(jù)結(jié)構(gòu),則其數(shù)據(jù)類型依然全部為字符串類型。

> m <- as.data.frame(m)
> m
           r1    r2    r3    r4
gene    gene1 gene2 gene3 gene4
CHANGE     up    up  down  down
score      12    23    50     2
p.value  0.01  0.02  0.07  0.05
> class(m)
[1] "data.frame"
> class(m$r3)
[1] "character"

若強(qiáng)行將某一列轉(zhuǎn)換成數(shù)值類型,則非數(shù)值的單元格將由NA代替。

> m$r3 <- as.numeric(m$r3)
Warning message:
NAs introduced by coercion 
> m
           r1    r2    r3    r4
gene    gene1 gene2    NA gene4
CHANGE     up    up    NA  down
score      12    23 50.00     2
p.value  0.01  0.02  0.07  0.05
  • 給矩陣畫熱圖
pheatmap::pheatmap(m)
image.png
  • 關(guān)閉聚類功能,使熱圖顏色與矩陣數(shù)值一一對(duì)應(yīng):
> pheatmap::pheatmap(m, cluster_rows = F, cluster_cols = F)
image.png

(三)數(shù)據(jù)框(data.frame)

  • 數(shù)據(jù)框是二維的。
  • 每列只允許一種數(shù)據(jù)類型,各列間的數(shù)據(jù)類型可以不相同。

I.數(shù)據(jù)框的來源

  1. 用代碼新建
  2. 由已有的數(shù)據(jù)轉(zhuǎn)換或處理得到
  3. 讀取表格文件
  4. R語(yǔ)言內(nèi)置數(shù)據(jù)
什么是熱圖?

熱圖是用顏色的深淺來表示數(shù)值的大小。

II.數(shù)據(jù)框的生成與操作

  1. 用函數(shù)data.frame()生成
> #新建和讀取數(shù)據(jù)框
> df1 <- data.frame(gene   = paste0("gene",1:4), #每行生成一個(gè)向量,作為數(shù)據(jù)框的一列
+                  change  = rep(c("up","down"),each = 2), #每行代碼用逗號(hào)分隔
+                  score   = c(5,3,-2,-4))
> df1
   gene change score
1 gene1     up     5
2 gene2     up     3
3 gene3   down    -2
4 gene4   down    -4
  1. 從文件中讀取

從CSV(逗號(hào)分隔符文件)文件中讀取數(shù)據(jù),生成數(shù)據(jù)框。函數(shù)read.csv()

> df2 <- read.csv("gene.csv")  #文件gene.csv需放在當(dāng)前的工作目錄下
> df2
   gene change score
1 gene1     up     5
2 gene2     up     3
3 gene3   down    -2
4 gene4   down    -4
  1. 數(shù)據(jù)框?qū)傩?/li>
> dim(df1)  #dim函數(shù)查看數(shù)據(jù)框的行數(shù)和列數(shù),dim表示維度的意思
[1] 4 3
> nrow(df1)  #只查看行數(shù)
[1] 4
> ncol(df1)  #只查看列數(shù)
[1] 3
#查看行名和列名
> rownames(df1)   #提取行名
[1] "1" "2" "3" "4"
> colnames(df1)   #提取列名
[1] "gene"   "change" "score" 
  1. 數(shù)據(jù)框取子集
  • 用$指定列名或列號(hào)來取數(shù)據(jù)框的某列
> df1$gene  #刪掉score,按tab鍵試試
[1] "gene1" "gene2" "gene3" "gene4"
> mean(df1$score)
[1] 0.5
  • 按坐標(biāo)、行列名、行列條件取子集
> ## 按坐標(biāo)
> df1[2,2]
[1] "up"
> df1[2,]
   gene change score
2 gene2     up     3
> df1[,2]
[1] "up"   "up"   "down" "down"
> df1[c(1,3),1:2]
   gene change
1 gene1     up
3 gene3   down
> #按名字
> df1[,"gene"]
[1] "gene1" "gene2" "gene3" "gene4"
> df1[,c('gene','change')]    #用$取子集的列,只能取1列。用[]可以取多列。
   gene change
1 gene1     up
2 gene2     up
3 gene3   down
4 gene4   down

> #按條件(邏輯值)——篩選score大于0的行
> df1[df1$score>0,]    #表示行進(jìn)行篩選,列都要
   gene change score
1 gene1     up     5
2 gene2     up     3
#思路拆解
> df1$score
[1]  5  3 -2 -4
> df1$score>0
[1]  TRUE  TRUE FALSE FALSE
> df1$score[df1$score>0]
[1] 5 3

> #篩選score > 0的基因
> df1[df1$score > 0,1]
[1] "gene1" "gene2"
> df1$gene[df1$score > 0]   #用于取子集的邏輯值向量與原集對(duì)應(yīng)即可
[1] "gene1" "gene2"
#第一種方式還可以保留數(shù)據(jù)框的格式
> df1[df1$score > 0,1,drop=F]
   gene
1 gene1
2 gene2
#將參數(shù)drop設(shè)置為FALSE,則只提取出對(duì)應(yīng)的字段,并保留原來的數(shù)據(jù)結(jié)構(gòu),不轉(zhuǎn)換成向量。
#第二種方式是不可以的,因?yàn)榈诙N方式首先提取出gene這一列(df1$gene)已經(jīng)是向量了,再取向量子集,仍然是向量。

#取數(shù)據(jù)框最后一列(不知道具體列數(shù))
> df1[,ncol(df1)]  #函數(shù)ncol()求出數(shù)據(jù)框的總列數(shù),最后一列即為第“總列數(shù)”列。
[1]  5  3 -2 -4
#取數(shù)據(jù)框除去最后一列的其他列
> df1[,-ncol(df1)] #減號(hào)表示除去該列意外其他列
   gene change
1 gene1     up
2 gene2     up
3 gene3   down
4 gene4   down

中括號(hào)里的逗號(hào),表示維度的分割。

重點(diǎn)與Tips:

  1. 數(shù)據(jù)框按照邏輯值取子集,TRUE對(duì)應(yīng)的行/列留下,F(xiàn)ALSE對(duì)應(yīng)的行/列丟掉。
  2. 用于取子集的邏輯值向量,與原集對(duì)應(yīng)即可,不必一定由原集生成。
  1. 數(shù)據(jù)框的修改
> #改一個(gè)格
> df1[3,3] <- 5
> df1
   gene change score
1 gene1     up     5
2 gene2     up     3
3 gene3   down     5
4 gene4   down    -4
> #改一整列
> df1$score <- c(12,23,50,2)     
> df1
   gene change score
1 gene1     up    12
2 gene2     up    23
3 gene3   down    50
4 gene4   down     2
> #增加一列
> df1$p.value <- c(0.01,0.02,0.07,0.05) 
> df1
   gene change score p.value
1 gene1     up    12    0.01
2 gene2     up    23    0.02
3 gene3   down    50    0.07
4 gene4   down     2    0.05

> #改行名和列名
> rownames(df1)
[1] "1" "2" "3" "4"
> colnames(df1)
[1] "gene"    "change"  "score"   "p.value"

> rownames(df1) <- c("r1","r2","r3","r4")

> #只修改某一行/列的名
> colnames(df1)[2] <- "CHANGE"

> df1
    gene CHANGE score p.value
r1 gene1     up    12    0.01
r2 gene2     up    23    0.02
r3 gene3   down    50    0.07
r4 gene4   down     2    0.05

Tips:

  1. 當(dāng)取用的列名為原數(shù)據(jù)框存在的列名,則賦值為修改改列內(nèi)容;當(dāng)取用的列名不存在與原數(shù)據(jù)框,則賦值為新增一列。
  1. 兩個(gè)數(shù)據(jù)框的連接

假設(shè)有三個(gè)數(shù)據(jù)框test1,test2,test3,如下:

> test1 <- data.frame(name = c('jimmy','nicker','Damon','Sophie'), 
+                     blood_type = c("A","B","O","AB"))
> test1
    name blood_type
1  jimmy          A
2 nicker          B
3  Damon          O
4 Sophie         AB
> test2 <- data.frame(name = c('Damon','jimmy','nicker','tony'),
+                     group = c("group1","group1","group2","group2"),
+                     vision = c(4.2,4.3,4.9,4.5))
> test2
    name  group vision
1  Damon group1    4.2
2  jimmy group1    4.3
3 nicker group2    4.9
4   tony group2    4.5
> 
> test3 <- data.frame(NAME = c('Damon','jimmy','nicker','tony'),
+                     weight = c(140,145,110,138))
> test3
    NAME weight
1  Damon    140
2  jimmy    145
3 nicker    110
4   tony    138

merge()函數(shù)將兩個(gè)數(shù)據(jù)框按照列名稱進(jìn)行合并。指定的列名稱取交集,其余列均包含在新數(shù)據(jù)框中。如下:

> merge(test1,test2,by="name")
    name blood_type  group vision
1  Damon          O group1    4.2
2  jimmy          A group1    4.3
3 nicker          B group2    4.9

當(dāng)列名稱不同時(shí),若仍舊需要按照這兩列取交集合并,則可以具體指定兩個(gè)列名稱,如下:(注意指定的列名稱順序需與前面指定的數(shù)據(jù)框順序?qū)?yīng))

> merge(test1,test3,by.x = "name",by.y = "NAME")
    name blood_type weight
1  Damon          O    140
2  jimmy          A    145
3 nicker          B    110

merge()函數(shù)的幫助文檔:

描述:將兩個(gè)數(shù)據(jù)框按照共同的列或行的名稱進(jìn)行合并。

格式:merge(x,y, by= intersect(names(x), names(y)),

         by.x= by, by.y= by, all=FALSE, all.x=all, all.y=all, sort=TRUE)

參數(shù):由上可知,默認(rèn)是取兩個(gè)數(shù)據(jù)框的共同相同名稱的列或者行?;蛘哌M(jìn)行單獨(dú)指定。默認(rèn)all=FALSE,表示只取共同列或行中相同值的內(nèi)容進(jìn)行合并,當(dāng)指定all=TRUE時(shí),取兩個(gè)數(shù)據(jù)框中指定行列的并集進(jìn)行合并,任一表中的缺失值,則用NA填充。

舉例:

> merge(test1, test2, by='name', all=T)
    name blood_type  group vision
1  Damon          O group1    4.2
2  jimmy          A group1    4.3
3 nicker          B group2    4.9
4 Sophie         AB   <NA>     NA
5   tony       <NA> group2    4.5

也可分別指定按照哪個(gè)數(shù)據(jù)框中的數(shù)據(jù)為標(biāo)準(zhǔn)進(jìn)行取值(即指定數(shù)據(jù)框中的數(shù)全部取,另一數(shù)據(jù)框數(shù)據(jù)取與之的交集。) 相應(yīng)的缺失值同樣用NA填充,如:

> merge(test1, test2, by='name', all.x = T)
    name blood_type  group vision
1  Damon          O group1    4.2
2  jimmy          A group1    4.3
3 nicker          B group2    4.9
4 Sophie         AB   <NA>     NA
> merge(test1, test2, by='name', all.y = T)
    name blood_type  group vision
1  Damon          O group1    4.2
2  jimmy          A group1    4.3
3 nicker          B group2    4.9
4   tony       <NA> group2    4.5

(四)列表(list)

列表可以裝各種數(shù)據(jù)結(jié)構(gòu)和類型。

I. 新建列表

#列表
l <- list(m1 = matrix(1:9, nrow = 3),
          m2 = matrix(2:9, nrow = 2))

> l
$m1
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

$m2
     [,1] [,2] [,3] [,4]
[1,]    2    4    6    8
[2,]    3    5    7    9

II.列表取子集

> l[[2]]   #列表的取子集,用兩個(gè)中括號(hào),表示取出其中的第幾個(gè)元素
     [,1] [,2] [,3] [,4]   #取出的是矩陣。
[1,]    2    4    6    8
[2,]    3    5    7    9
> l$m1  #也可以用$符號(hào)指定元素的名稱來取子集
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

Tips:

列表取子集時(shí),用兩個(gè)中括號(hào),取出來的是指定元素本來的數(shù)據(jù)結(jié)構(gòu)。如上例中,取出的子集是矩陣。

若用1個(gè)中括號(hào),取出來的子集數(shù)據(jù)結(jié)構(gòu)仍然是列表,內(nèi)容雖然一致。

某些時(shí)候,一些函數(shù)只能對(duì)矩陣、向量等數(shù)據(jù)結(jié)構(gòu)進(jìn)行處理,而不支持列表,這時(shí)候需要嚴(yán)格區(qū)分所取出的數(shù)據(jù)結(jié)構(gòu)具體是哪一種。

> l
$m1
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

$m2
     [,1] [,2] [,3] [,4]
[1,]    2    4    6    8
[2,]    3    5    7    9

> class(l[[1]])
[1] "matrix" "array" 
> class(l[1])
[1] "list"
> pheatmap::pheatmap(l[[1]])  #可以作圖
> pheatmap::pheatmap(l[1])    #報(bào)錯(cuò)
Error in dist(mat, method = distance) : 
  'list' object cannot be coerced to type 'double'

重要練習(xí)題:

# 3.篩選test中,Species列的值為a或c的行
test[test$Species!="b",]
test[test$Species=="a"|test$Species=="c",]
test[test$Species %in% c("a","c"),]   

第三個(gè)答案反復(fù)體會(huì)。

四、函數(shù)

image.png

function為編寫函數(shù)的函數(shù)。

列出一個(gè)包里有哪些函數(shù)或數(shù)據(jù)

ls('package:stringr')  #列出stringr包中有哪些函數(shù)
最后編輯于
?著作權(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)容

  • ??R語(yǔ)言是數(shù)學(xué)研究工作者設(shè)計(jì)的一種數(shù)學(xué)編程語(yǔ)言,主要用于統(tǒng)計(jì)分析、繪圖、數(shù)據(jù)挖掘。R語(yǔ)言是解釋運(yùn)行的語(yǔ)言(與C語(yǔ)...
    生信師兄閱讀 781評(píng)論 0 2
  • 一.R環(huán)境設(shè)置 嘗試在線環(huán)境 你真的不需要設(shè)置自己的環(huán)境來開始學(xué)習(xí)R編程語(yǔ)言。 原因很簡(jiǎn)單,我們已經(jīng)在線設(shè)置了R編...
    JackHCC閱讀 1,168評(píng)論 0 1
  • 一.R環(huán)境設(shè)置 嘗試在線環(huán)境 你真的不需要設(shè)置自己的環(huán)境來開始學(xué)習(xí)R編程語(yǔ)言。 原因很簡(jiǎn)單,我們已經(jīng)在線設(shè)置了R編...
    JackHCC閱讀 663評(píng)論 0 0
  • 補(bǔ)充[ZHUHAI_Biotrainee] 第一周_課堂總結(jié)內(nèi)容:http://www.itdecent.cn/...
    ShanSly閱讀 766評(píng)論 0 3
  • 創(chuàng)建R-project 腳本編輯器 腳本編輯器控制臺(tái)對(duì)象/變量列表,歷史命令文件/圖片/幫助 設(shè)置字體 TOOLS...
    成靜_fcf9閱讀 622評(píng)論 0 0

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