重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——3. 單細(xì)胞分析中的R/Bioconductor簡(jiǎn)介(2)

3.5 向量子集
向量子集是R的主要優(yōu)點(diǎn)之一。它非常靈活且功能強(qiáng)大。子集有三種類型:1. 按索引(數(shù)字)2. 按名稱(字符)3. 按條件(邏輯)。要進(jìn)行取子集操作,需要輸入變量名稱并在方括號(hào)中指定所需元素。數(shù)值子集與許多其他語言相反,R中的向量索引是基于1的,也就是說,第一個(gè)元素的索引為1。

> x = c(1,4,7,9,10,24,100)
> x[4]
[1] 9
> x[c(1,4,5)]
[1]  1  9 10
> x[c(6,1,5,1,2,6,6)]
[1] 24  1 10  1  4 24 24
> x[2:5]
[1]  4  7  9 10
> x[length(x):1]
[1] 100  24  10   9   7   4   1
> y = x[c(5,5,1:3)]
> y
[1] 10 10  1  4  7

負(fù)索引可用于排除特定元素:

> x[-1:-3]
[1]   9  10  24 100
> x[-length(x)]
[1]  1  4  7  9 10 24

3.5.1 按名稱取子集
命名向量可以通過名稱進(jìn)行索引:

> names(x) = letters[1:length(x)]
> x
  a   b   c   d   e   f   g 
  1   4   7   9  10  24 100 
> x['a']
a 
1 
> x[c('b','a','c')]
b a c 
4 1 7

注意!R允許名稱重復(fù)。在這種情況下,將返回第一個(gè)匹配項(xiàng):

> names(x)[3] = 'a'
> x
  a   b   a   d   e   f   g 
  1   4   7   9  10  24 100 
> x['a']
a 
1

3.5.2 按邏輯值取子集
按邏輯值取子集用于有條件地選擇某些元素。例如,可以獲取所有奇數(shù)值:

> x[x %% 2 == 1]
a a d 
1 7 9 
> x[x>9]
  e   f   g 
 10  24 100

括號(hào)內(nèi)的邏輯值不一定基于向量計(jì)算:

> x[c(T,F,F,T,F,T,T)]
  a   d   f   g 
  1   9  24 100 
> x[c(T,F)]
  a   a   e   g 
  1   7  10 100

3.6 列表(Lists)
向量可用于存儲(chǔ)相同類型的值。如果需要存儲(chǔ)不同類型的信息(例如一個(gè)人的姓名和年齡),它們就不起作用。R列表允許存儲(chǔ)任何類型的變量,包括其他列表。列表非常靈活,可以滿足您的所有需求。列表可以通過類似于c函數(shù)的list函數(shù)創(chuàng)建。

> l = list(1,'a',2:4,c('b','c'))
> l
[[1]]
[1] 1

[[2]]
[1] "a"

[[3]]
[1] 2 3 4

[[4]]
[1] "b" "c"

> typeof(l)
[1] "list"
> str(l)
List of 4
 $ : num 1
 $ : chr "a"
 $ : int [1:3] 2 3 4
 $ : chr [1:2] "b" "c"
> l = list(name='Sam',yob=2001L,weight=70.5)
> str(l)
List of 3
 $ name  : chr "Sam"
 $ yob   : int 2001
 $ weight: num 70.5
> l[3:2]
$weight
[1] 70.5

$yob
[1] 2001

> l[c('weight','name')]
$weight
[1] 70.5

$name
[1] "Sam"

> l[c(F,T,F)]
$yob
[1] 2001

通過[運(yùn)算符進(jìn)行列表索引將返回原始列表的子列表。要獲取列表的特定元素,應(yīng)使用[[運(yùn)算符:

> l2 = l[3]
> typeof(l2)
[1] "list"
> l2
$weight
[1] 70.5

> l3 = l[[3]]
> typeof(l3)
[1] "double"
> l3
[1] 70.5

運(yùn)算符[[看起來很不優(yōu)雅,因此對(duì)于命名向量,可以使用與[[完全相同的運(yùn)算符$

> l$name
[1] "Sam"
> typeof(l$name)
[1] "character"

任何類型的數(shù)據(jù)都可以存儲(chǔ)在列表中:

> l = list(abc=letters[1:4],innerlist=list(a='a',b=1:10),sumfun = sum)
> str(l)
List of 3
 $ abc      : chr [1:4] "a" "b" "c" "d"
 $ innerlist:List of 2
  ..$ a: chr "a"
  ..$ b: int [1:10] 1 2 3 4 5 6 7 8 9 10
 $ sumfun   :function (..., na.rm = FALSE)  
> l$innerlist$b
 [1]  1  2  3  4  5  6  7  8  9 10
> l$innerlist$b[5:1]
[1] 5 4 3 2 1
> l$sumfun(1:10)
[1] 55

3.7 字典(Dictionaries)
與Python不同,R沒有字典(哈希表)對(duì)象。大多數(shù)情況下,可以使用命名向量(或列表)代替(但要小心名稱重復(fù))。否則,可以使用環(huán)境作為哈希,但這超出了本課程的范圍。
3.8 類(Classes)
R支持至少三種不同的面向?qū)ο缶幊蹋∣OP)系統(tǒng)。大多數(shù)R用戶不需要?jiǎng)?chuàng)建自己的類,但了解這些系統(tǒng)以處理現(xiàn)有的包是值得的。我們將簡(jiǎn)要討論其中兩個(gè):S3和S4,讓我們從S3系統(tǒng)開始。在OOP范式中,每個(gè)變量都根據(jù)其類進(jìn)行處理。R允許向任何變量添加屬性,可以使用屬性或attr函數(shù)訪問、設(shè)置和修改屬性。

> v = c(a=1,b=10,z=7)
> attributes(v)
$names
[1] "a" "b" "z"

因此,向量值的名稱是向量屬性之一。通常,所有屬性都通過特定函數(shù)(例如names)訪問。S3系統(tǒng)使用稱為class的屬性,可以使用函數(shù)class訪問。我們將使用factor類來說明S3系統(tǒng)。因子是為存儲(chǔ)分類信息(例如性別(男/女)或物種(狗/貓/人))而開發(fā)的類。分類信息可以存儲(chǔ)為文本,但有時(shí)因子很有用。

> f = factor(c('m','m','f'),levels = c('m','f','unk'))
> typeof(f)
[1] "integer"
> class(f)
[1] "factor"
> f
[1] m m f
Levels: m f unk
> f2 = unclass(f)
> class(f2)
[1] "integer"
> f2
[1] 1 1 2
attr(,"levels")
[1] "m"   "f"   "unk"

一些R函數(shù)可以分派函數(shù)調(diào)用,即根據(jù)其參數(shù)調(diào)用特定函數(shù)。在這種情況下,它只是調(diào)用一個(gè)函數(shù),該函數(shù)的名稱是由點(diǎn)分隔的通用函數(shù)名和類名組合而成:

> print.factor(f2)
[1] 1 1 2
Levels: m f unk

雖然f2現(xiàn)在不是一個(gè)因子,但如果我們手動(dòng)調(diào)用相應(yīng)的函數(shù),它仍然可以被打印為因子。
3.9 二維數(shù)據(jù)結(jié)構(gòu)
到目前為止我們討論的類型都是一維的,但有些數(shù)據(jù)(基因到細(xì)胞表達(dá)矩陣,或樣本元數(shù)據(jù))需要二維(甚至三維)結(jié)構(gòu)(又名表)來存儲(chǔ)。R中有兩種二維結(jié)構(gòu):數(shù)組(arrays)和數(shù)據(jù)框(data.frames)。數(shù)組允許僅存儲(chǔ)單一類型的值,因?yàn)閿?shù)組內(nèi)部是向量。Data.frames可以有不同類型的列,但每列只能包含單一類型的值。Data.frames內(nèi)部是列的列表。
3.9.1 數(shù)組(Arrays)

> a = matrix(1:12,ncol=3)
> a
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12
> typeof(a)
[1] "integer"
> class(a)
[1] "matrix" "array" 
> attributes(a)
$dim
[1] 4 3

> dim(a)
[1] 4 3
> nrow(a)
[1] 4
> ncol(a)
[1] 3
> colnames(a) = letters[1:ncol(a)]
> rownames(a) = LETTERS[1:nrow(a)]
> a
  a b  c
A 1 5  9
B 2 6 10
C 3 7 11
D 4 8 12

可以使用相同的三種方法(按數(shù)字、按名稱和邏輯)執(zhí)行數(shù)組取子集,但索引將分別應(yīng)用于行和列:

> a[1:2,3:1]
   c b a
A  9 5 1
B 10 6 2
> a[,2:3]
  b  c
A 5  9
B 6 10
C 7 11
D 8 12
> a[c(4,2,3),]
  a b  c
D 4 8 12
B 2 6 10
C 3 7 11
> a[c('D','C'),c('b','b')]
  b b
D 8 8
C 7 7
> a[,c(T,F,T)]
  a  c
A 1  9
B 2 10
C 3 11
D 4 12
> a[a[,1]>2,]
  a b  c
C 3 7 11
D 4 8 12
> a[-2,c('c','b')]
   c b
A  9 5
C 11 7
D 12 8

3.9.2 數(shù)據(jù)框(Data.frames)
Data.frame與矩陣非常相似,但它允許在不同的列中存儲(chǔ)不同類型的值。Data.frame可以通過指定列通過data.frame函數(shù)創(chuàng)建,所有列應(yīng)為相同長(zhǎng)度的向量。

> d = data.frame(name=c('Sam','John','Sara'),age=c(40,14,51),sex=factor('m','m','f'))
> class(d)
[1] "data.frame"
> typeof(d)
[1] "list"
> d
  name age sex
1  Sam  40   f
2 John  14   f
3 Sara  51   f

與數(shù)組類似,data.frames可以有行名和列名。唯一的區(qū)別是data.frame行名應(yīng)該是唯一的:

> colnames(d)
[1] "name" "age"  "sex" 
> rownames(d) = c('Sm','Jn','Sr')
> d
   name age sex
Sm  Sam  40   f
Jn John  14   f
Sr Sara  51   f

data.frames的索引與數(shù)組索引相同:

> d[c(3,1),c('sex','name')]
   sex name
Sr   f Sara
Sm   f  Sam

但由于data.frames是列表,因此也可以使用運(yùn)算符$來獲取單列:

> d$age
[1] 40 14 51

往期內(nèi)容:
重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——2. scRNA-Seq原始測(cè)序數(shù)據(jù)處理(1)
重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——2. scRNA-Seq原始測(cè)序數(shù)據(jù)處理(2)
重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——3. 單細(xì)胞分析中的R/Bioconductor簡(jiǎn)介(1)

?著作權(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)容

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