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)雅稚照,因此對于命名向量蹂空,可以使用與[[
完全相同的運(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沒有字典(哈希表)對象。大多數(shù)情況下上枕,可以使用命名向量(或列表)代替(但要小心名稱重復(fù))咐熙。否則,可以使用環(huán)境作為哈希辨萍,但這超出了本課程的范圍棋恼。
3.8 類(Classes)
R支持至少三種不同的面向?qū)ο缶幊蹋∣OP)系統(tǒng)。大多數(shù)R用戶不需要?jiǎng)?chuàng)建自己的類锈玉,但了解這些系統(tǒng)以處理現(xià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)為相同長度的向量刹枉。
> 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原始測序數(shù)據(jù)處理(1)
重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——2. scRNA-Seq原始測序數(shù)據(jù)處理(2)
重生之我在劍橋大學(xué)學(xué)習(xí)單細(xì)胞RNA-seq分析——3. 單細(xì)胞分析中的R/Bioconductor簡介(1)