R語言數(shù)據(jù)結(jié)構(gòu)主要有以下四種:
1.向量
2.數(shù)據(jù)框
3.矩陣
4.列表
四種數(shù)據(jù)結(jié)構(gòu)帽氓,重點(diǎn)掌握向量和數(shù)據(jù)框
Vector向量:一維父虑,數(shù)值型媳否,字符型(加引號)揉阎,邏輯型舆逃。
matrix矩陣:二維蚂维,只允許一種數(shù)據(jù)類型。
data.frame數(shù)據(jù)框:二維路狮,每列只允許一種數(shù)據(jù)類型虫啥,列與列之間的數(shù)據(jù)類型是否相同不管。
list列表:包羅萬象奄妨,可以包含向量涂籽,矩陣,數(shù)據(jù)框等砸抛。
判斷數(shù)據(jù)結(jié)構(gòu)的函數(shù):class()
向量的詳細(xì)講解在上一篇文章评雌,以下主要講數(shù)據(jù)框,矩陣直焙,列表:
2.數(shù)據(jù)框
2.1 數(shù)據(jù)框來源
(1)在R中新建:用代碼生成景东。
(2)由已有數(shù)據(jù)轉(zhuǎn)換或處理得到:向量組裝,矩陣轉(zhuǎn)換奔誓,或是從列表里提取斤吐。
(3)從文件中讀取:把文件導(dǎo)入到R語言里頭厨喂,一個常規(guī)的表格讀入到R語言里就是一個數(shù)據(jù)框和措。
(4)內(nèi)置數(shù)據(jù)集:安裝某些R包是自帶,有些直接就可以用杯聚,如irirs
2.2.1 新建數(shù)據(jù)框
df <- data.frame(gene = paste0("gene",1:4),
change = rep(c("up","down"),each = 2),
score = c(5,3,-2,-4))
df
# gene change score
# 1 gene1 up 5
# 2 gene2 up 3
# 3 gene3 down -2
# 4 gene4 down -4
##有多少個等號就有多少列臼婆,多少個變量名(向量)。
##向量的長度(元素個數(shù))決定行數(shù)幌绍,每個向量的長度要一致颁褂。
以下大部分操作使用的數(shù)據(jù)框?yàn)閐f
2.2.2 從文件中讀取數(shù)據(jù)框
df2 <- read.csv("gene.csv")
df2
# gene change score
# 1 gene1 up 5
# 2 gene2 up 3
# 3 gene3 down -2
# 4 gene4 down -4
##簡單的表格讀取和賦值
##文件是之前用csv格式保存好故响,文件一定要放在當(dāng)前工作目錄下,小潔老師幫我們準(zhǔn)備好的csv文件
2.2 數(shù)據(jù)框?qū)傩?/h4>
幾個重要的函數(shù):查看數(shù)據(jù)框的行數(shù)和列數(shù)颁独,行名和列名彩届;以及單獨(dú)查行的數(shù)量,列的數(shù)量
dim()#查數(shù)據(jù)框幾行幾列誓酒,維度樟蠕。
rownames(df)#查看行名。
colnames(df)#查看列名靠柑。
nrow()#查數(shù)據(jù)框有幾行寨辩。
ncol()#查數(shù)據(jù)框有幾列。
df <- data.frame(gene = paste0("gene",1:4),
change = rep(c("up","down"),each = 2),
score = c(5,3,-2,-4))
##以df數(shù)據(jù)框演示
dim(df)#查數(shù)據(jù)框幾行幾列
#[1] 4 3
##返回?cái)?shù)據(jù)框的維度歼冰,即行數(shù)和列數(shù)靡狞。df數(shù)據(jù)框4行3列
nrow(df)#數(shù)據(jù)框有幾行
#[1] 4
##統(tǒng)計(jì)數(shù)據(jù)框有幾行
ncol(df)#數(shù)據(jù)框有幾列
#[1] 3
##統(tǒng)計(jì)數(shù)據(jù)框有幾列
rownames(df)#行名
#[1] "1" "2" "3" "4"
##顯示數(shù)據(jù)框的所有行名
colnames(df)#列名
#[1] "gene" "change" "score"
##顯示數(shù)據(jù)框的所有列名
2.3 數(shù)據(jù)框取子集
數(shù)據(jù)框取子集有幾種方法:$
符號,坐標(biāo)隔嫡,名字甸怕,邏輯值
在[,]
里,行在前面(左邊)腮恩,列在后面(右邊)梢杭,行與列用逗號,
隔開:[行,列]
2.3.1 使用$
取列
df$score
##取df數(shù)據(jù)框的score列
#刪掉score,按tab鍵試試秸滴,使用tab鍵補(bǔ)全武契,避免拼寫錯誤
mean(df$score)
#[1] 0.5
##求平均值,其實(shí)score列就是一個向量缸榛,可以進(jìn)行運(yùn)算
2.3.2 按坐標(biāo)取子集
df[2,2]
#[1] "up"
##取第2行和第2列的格子里的內(nèi)容
df[2,]
#2 gene2 up 3
##取第二行吝羞,列的位置不寫內(nèi)容表示全都要,第二行對應(yīng)的列位置上的內(nèi)容都要
df[,2]
#[1] "up" "up" "down" "down"
##取第二列内颗,行的位置不寫內(nèi)容表示全都要,第二列對應(yīng)的行位置上的內(nèi)容都要
x <- 3:10
x[2,6]
##出現(xiàn)報(bào)錯敦腔,向量不能這樣用下標(biāo)取子集
x[c(2,6)]
##用c()函數(shù)就不會報(bào)錯
##中括號里的逗號均澳,表示維度的分割
df[c(1,3),1:2]
# gene change
# 1 gene1 up
# 3 gene3 down
df[1:3,c(1,3)]
# gene score
# 1 gene1 5
# 2 gene2 3
# 3 gene3 -2
##對于提取數(shù)據(jù)框的行數(shù)和列數(shù),取連續(xù)就用冒號:符衔,去間斷的用函數(shù)c()函數(shù)找前,用逗號,隔開
中括號里的逗號,表示維度的分割
2.3.3 按列的名字
df[,"gene"]
#[1] "gene1" "gene2" "gene3" "gene4"
##可以單獨(dú)提取一列判族,在這和$的用法一樣
df[,c('gene','change')]
# gene change
# 1 gene1 up
# 2 gene2 up
# 3 gene3 down
# 4 gene4 down
##可以提取多列躺盛,用函數(shù)c(),用$只能每次提取一列形帮。
2.3.4 按條件(邏輯值)
- 篩選score對于0的行:
df[df$score>0,]
# gene change score
# 1 gene1 up 5
# 2 gene2 up 3
##對行進(jìn)行篩選槽惫。把df$score>0看做一個整體周叮,返回是一個邏輯值,篩選score列大于0的行界斜。
##細(xì)節(jié)理解如下:
df$score
#[1] 5 3 -2 -4
df$score > 0
#[1] TRUE TRUE FALSE FALSE
df$score[df$score>0]
#[1] 5 3
##df$score看在是一個向量仿耽,現(xiàn)在是要把所在的行篩選出來,對數(shù)據(jù)框而言各薇,行在左邊项贺,所以把篩選條件放在行的位置
df[df$score>0,]
# gene change score
#1 gene1 up 5
#2 gene2 up 3
數(shù)據(jù)框按照邏輯值取子集,TRUE對應(yīng)的行/列留下峭判,F(xiàn)ALSE對應(yīng)的行/列去掉开缎。
- 篩選score對于0的基因:
df[df$score>0,1]
#[1] "gene1" "gene2"
##按數(shù)據(jù)框取子集,要知道基因是在哪一列林螃,在第1列.
df$gene[df$score>0]
#[1] "gene1" "gene2"
##按照向量取子集奕删,對基因所在的向量操作。
##類似y[x>0],x生成的邏輯值給y來用治宣,現(xiàn)在的gene列和score列有對應(yīng)關(guān)系急侥。以前單獨(dú)向量的y和x沒有綁定關(guān)系,這是數(shù)據(jù)框帶來隱藏的知識點(diǎn)侮邀。
- 變量賦值思維:
nn = c('gene','change')
df[,nn]##相當(dāng)于代碼df[,c('gene','change')]坏怪,為嵌套代碼
##用nn替代 c('gene','change'),以后會多次出現(xiàn)時(shí)避免寫錯和冗余绊茧,還有以后只在nn = c('gene','change')出修改铝宵,聯(lián)想到ids的賦值。
##變量思想华畏,賦值思想
df[,3]
#[1] 5 3 -2 -4
##取df的第三列
df[,ncol(df)]
#[1] 5 3 -2 -4
##ncol(df)返回為3鹏秋,數(shù)據(jù)框只有3列,其實(shí)是取第ncol列亡笑,最后一列侣夷。
##以后聯(lián)想到刪減或是新增一列,關(guān)鍵信息永遠(yuǎn)都在最后一列ncol(df)仑乌。
df[,-ncol(df)]
# gene change
# 1 gene1 up
# 2 gene2 up
# 3 gene3 down
# 4 gene4 down
##-ncol(df)表示不要最后一列百拓。
##好奇探索,提取最后一行和去掉最后一行
df[nrow(df),]
df[-nrow(df),]
##練習(xí)題:篩選test中晰甚,最后一列(Species)值為a或c的行(沒有test數(shù)據(jù)框沒法練習(xí)衙传,test由生信技能樹提供)
test2 <- test[test$Species%in%!="b",]
##這種做法適合向量里有3選2,如果是50選20比較麻煩
test2 <- test[test$Species %in% c('a','c'),]
##最優(yōu)的做法厕九,可適用于很多場景蓖捶。不用==,因?yàn)閍,c固定等位循環(huán)補(bǔ)齊不符合題目要求
##小潔老師出的題和答案思路廣扁远。
2.4 數(shù)據(jù)框修改
2.4.1 改一個格(值)
df[3,3]<- 5
##按坐標(biāo)修改一個格子,把第三行和第三列的數(shù)字改為5
df
2.4.2 改一整列
df$score<-c(12,23,50,2)
##修改某一列,一列也是一個向量俊鱼,修改記得長度一致
df
2.4.3 增加一列(一般默認(rèn)放在最后的一列)
df$p.value <-c(0.01,0.02,0.07,0.05)
##增加某一列
df
##為什么不新增一行刻像,一行里有字符型,數(shù)值型亭引,不能以一個向量的形式存在绎速,會把那一行的數(shù)值型弄成字符型。
##新增一列焙蚓,因?yàn)榱信c列之間是可以相對獨(dú)立運(yùn)行的纹冤,數(shù)據(jù)框所有的操作都是圍繞列來操作的。
##如果要新增行购公,把兩個類似的表格用rbind()函數(shù)拼在一起萌京。
2.4.4 修改行名和列名
nrow(df)##先看看有幾行
rownames(df) <- c("r1","r2","r3","r4")
ncol(df)##先看看有幾列
colnames(df) <- c('Gene','differ','point','P')
##行名和列名返回是向量,R語言里任何函數(shù)的返回結(jié)果宏浩,要符合R語言內(nèi)部規(guī)則知残,了解R語言的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)類型很重要。修改數(shù)據(jù)框行名或是列名比庄,相當(dāng)于對一個向量進(jìn)行修改就相當(dāng)于重新賦值求妹。
2.4.5 只修改某一行/列的名
colnames(df)[2]="CHANGE"
##修改第二列的列名,相當(dāng)于對向量取子集并賦值
df
修改第二列的列名佳窑,就是修改列名這個向量的第二個元素
2.5 兩個數(shù)據(jù)框的連接
test1 <- data.frame(name = c('jimmy','nicker','Damon','Sophie'),
blood_type = c("A","B","O","AB"))
test1
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
2.5.1 兩個數(shù)據(jù)框取交集連接:merge函數(shù)
- 只取共同的制恍,沒有共同的去掉
merge(test1,test2,by="name")
##by="name",共同的列
- 兩個數(shù)據(jù)框"列名"不一樣的連接:使用merge()函數(shù)
test1 <- data.frame(name = c('jimmy','nicker','Damon','Sophie'),
blood_type = c("A","B","O","AB"))
test1
test3 <- data.frame(NAME = c('Damon','jimmy','nicker','tony'),
weight = c(140,145,110,138))
test3
###列名不同的兩個數(shù)據(jù)框第一種連接方式神凑,把一個數(shù)據(jù)框的列名修改后再連接
colnames(test3)[1]="name"
##列名不同的兩個數(shù)據(jù)框第二種方式:某一列有交集净神,但是列名不一樣的連接
merge(test1,test3,by.x = "name",by.y = "NAME")
##注意代碼里的數(shù)據(jù)與之對應(yīng)列名的順序不能搞錯,原來的代碼:
#merge(x=test1,y=test3,by.x = "name",by.y = "NAME")#把最前面的x=和y=省略
##要求:共同的一列且要存在交集
?merge
#查看幫助文檔
2.5.2 兩個數(shù)據(jù)框左連接溉委,右連接鹃唯,內(nèi)連接
https://blog.csdn.net/weixin_39718006/article/details/110516670
根據(jù)值匹配合并數(shù)據(jù)框:左連接、右連接瓣喊、全連接坡慌、內(nèi)連接、半連接藻三、反連接
left_join(x, y, by)
right_join(x, y, by)
full_join(x, y, by)
inner_join(x, y, by)
semi_join(x, y, by)
anti_join(x, y, by)
后續(xù)的筆記會有詳細(xì)介紹
3.矩陣
3.1 矩陣新建和取子集
3.2.1 新建矩陣
m <- matrix(1:9, nrow = 3)
##1:9,1到9個數(shù)字八匠,排成3行。參數(shù)nrow=3 或是 ncol=3都可以
# [,1] [,2] [,3]
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
##沒有行名和列名的矩陣
3.2.2 矩陣取子集:[ ]
矩陣不能用$
符號取子集
m[2,]
m[,1]
m[2,3]
m[2:3,1:2]
m
3.2 矩陣的轉(zhuǎn)置和轉(zhuǎn)換
t():轉(zhuǎn)置函數(shù)趴酣,行與列的互換
as.data.frame():轉(zhuǎn)換,把矩陣變?yōu)閿?shù)據(jù)框坑夯,用as.matrix()函數(shù)也能把數(shù)據(jù)框變?yōu)榫仃?/p>
colnames(m) <- c("a","b","c")
#加列名
t(m)
#行變列岖寞,列變行,t()轉(zhuǎn)置函數(shù)
as.data.frame(m)
##把m矩陣轉(zhuǎn)換為數(shù)據(jù)框
class(m)
##仍舊是矩陣柜蜈,要賦值才真正發(fā)生保存的變化仗谆,df=as.data.frame(m)
as.matrix(df)
##把數(shù)據(jù)框df轉(zhuǎn)換為矩陣
##as開頭表示轉(zhuǎn)換
3.3 矩陣畫熱圖
m
# a b c
# [1,] 1 4 7
# [2,] 2 5 8
# [3,] 3 6 9
pheatmap::pheatmap(m)
聚類指巡,相似的行,相似的列會聚在一起隶垮。熱圖自動聚類藻雪,行和列的相對位置發(fā)生了變化,只是列與列狸吞,行與行之間的變化規(guī)律勉耀。
熱圖默認(rèn)聚類,修改參數(shù)蹋偏,不讓聚類便斥,熱圖與表達(dá)矩陣對應(yīng)。
pheatmap::pheatmap(m,cluster_rows = F,cluster_cols =F )
##熱圖默認(rèn)為T威始,行聚類枢纠,列聚類,改為F就不聚類黎棠,使用tab鍵補(bǔ)全晋渺,參數(shù)不需要手打字。
默認(rèn)的設(shè)置不符合自己的預(yù)期脓斩,可以子啊作者允許的范圍內(nèi)定義木西。
查看函數(shù)幫助文檔,參考修改俭厚,達(dá)到自己的要求户魏。
4.列表
4.1列表新建
l <- list(m1 = matrix(1:9, nrow = 3),
m2 = matrix(2:9, nrow = 2))
l
##生成列表的函數(shù)list(),列表l由m1和m2兩個元素組成挪挤。
列表沒有列名和行名叼丑,只有元素的名字。列表可以由數(shù)據(jù)框扛门,矩陣鸠信,向量,單獨(dú)的一個數(shù)字都可以組成论寨。
4.2 列表取子集:[[]]
星立,$
列表沒有行和列的概念,只有元素葬凳,取子集的兩種方式:[[]]
绰垂,$
,
l[[2]]
##取列表第2個元素
l$m1
##取列表第1個元素
$
有兩個作用:數(shù)據(jù)框取子集和列表取子集火焰。在矩陣和向量里不能用$
劲装。
用class()
函數(shù)更能具體說明問題,判斷數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)類型
df <- data.frame(gene = paste0("gene",1:4),
change = rep(c("up","down"),each = 2),
score = c(5,3,-2,-4))
class(df)
#[1] "data.frame"
class(df$gene)
#[1] "character"
class(df$score)
#[1] "numeric"
class(df$change)
#[1] "character"
5.補(bǔ)充知識
5.1元素的"名字" -names()
scores = c(100,59,73,95,45)
names(scores) = c("jimmy","nicker","Damon","Sophie","tony")
scores
# jimmy nicker Damon Sophie tony
# 100 59 73 95 45
##在一種簡單的數(shù)據(jù)結(jié)構(gòu)里容納兩種不同的信息,好處在向量里容納不同的兩種信息占业,但是名字僅僅是向量的一個屬性绒怨,就是說,不會因?yàn)橄蛄繐碛忻侄淖兯旧硎菙?shù)值型向量的事實(shí)谦疾,有無名字都不會改變該向量為數(shù)值型向量南蹂。名字的用處是用于提子集,如下:
scores["jimmy"]
# jimmy
# 100
##提取單個元素的分?jǐn)?shù)念恍,等同于代碼:scores[1]
scores[c("jimmy","nicker")]
# jimmy nicker
# 100 59
##提取多個元素的分?jǐn)?shù)六剥,用c()函數(shù),等同于代碼:scores[c(1,2)]
names(scores)[scores>60]
#[1] "jimmy" "Damon" "Sophie"
##以后應(yīng)用在提取表達(dá)量大于多少的基因
scores[scores>60]
# jimmy Damon Sophie
# 100 73 95
5.2 刪除變量
##每次賦值后環(huán)境里都會多一個變量樊诺,引進(jìn)后再推出去仗考,即刪除。
rm(l)
##刪除一個變量词爬。
rm(df,m)
##刪除多個
rm(list = ls())
##刪除全部秃嗜,常用,每次在分析數(shù)據(jù)(或是調(diào)試代碼)第一句都會是這句代碼顿膨。清空環(huán)境锅锨,后面實(shí)戰(zhàn)反復(fù)出現(xiàn)。
control l
##按control 和 l鍵恋沃,清空控制臺必搞。
6. 數(shù)據(jù)結(jié)構(gòu)的總結(jié):
說明
以上內(nèi)容是聽生信技能樹小潔老師的R語言線上課,根據(jù)自己的理解記錄下來囊咏,小潔老師授課非常細(xì)心恕洲,對不同水平的同學(xué)都照顧到,并且補(bǔ)充很多技巧以及注意事項(xiàng)梅割。
認(rèn)識R語言的四種數(shù)據(jù)結(jié)構(gòu)霜第,小潔老師強(qiáng)調(diào)重點(diǎn)掌握向量和數(shù)據(jù)框,在實(shí)戰(zhàn)中遇到很多數(shù)據(jù)結(jié)構(gòu)都是數(shù)據(jù)框户辞,表達(dá)矩陣可以轉(zhuǎn)化為數(shù)據(jù)框泌类,數(shù)據(jù)框的一列可以看做是一個向量。小潔老師把實(shí)戰(zhàn)中會需要的操作融入到練習(xí)題底燎,在實(shí)戰(zhàn)中能聯(lián)想起小潔老師講過的知識點(diǎn)刃榨。