劉小澤寫于2018.8.27-28
我們?nèi)粘J褂肦一般不會(huì)使用它的編程工作(即寫R包的任務(wù)),許許多多的的生信函數(shù)仲墨、統(tǒng)計(jì)軟件也都是現(xiàn)成的括荡,我們要做的最繁瑣、最耗時(shí)的工作就是對(duì)數(shù)據(jù)進(jìn)行整理提揍。我們要做的就是將數(shù)據(jù)轉(zhuǎn)換成函數(shù)能夠識(shí)別處理的格式啤月。一般從.txt、.csv中讀入的數(shù)據(jù)都需要對(duì)結(jié)構(gòu)進(jìn)行轉(zhuǎn)換劳跃,例如:添加谎仲、刪除、修改刨仑、排序郑诺、篩選
1 數(shù)據(jù)讀入
-
一般使用read.table讀取.txt格式夹姥,用read.csv讀取excel格式文件【前提將excel保存成csv】
cars = read.csv(mtcars.csv) #這里就是做個(gè)演示,其實(shí)mtcars數(shù)據(jù)集是內(nèi)置的辙诞,直接cars = mtcars就可以
-
讀入后用class判斷類型辙售,另外還可以用
is.data.frame(cars) is.vector() is.array() is.na() is.null()#查看為空的內(nèi)容 methods(is)#查看全部關(guān)于is的內(nèi)容
-
轉(zhuǎn)換數(shù)據(jù)格式
#同樣內(nèi)置的數(shù)據(jù)集state.x77,先看一下他的類型 class(state.x77) #是matrix #matrix轉(zhuǎn)換成data.frame as.data.frame(state.x77) #注意:矩陣matrix轉(zhuǎn)換成數(shù)據(jù)框沒什么問題飞涂,但是反過來數(shù)據(jù)框要轉(zhuǎn)位矩陣可能就有問題旦部,因?yàn)榫仃嚤仨氁髷?shù)據(jù)同為字符串型或者同為數(shù)值型 as.matrix(data.frame(state.region,state.x77)) #結(jié)果就是這樣:全變成了字符型 #state.region Population Income Illiteracy Life.Exp Murder HS.Grad Frost #Alabama "South" " 3615" "3624" "2.1" "69.05" "15.1" "41.3" " 20" as.list() #轉(zhuǎn)換成列表 as.vector() #轉(zhuǎn)換成因子
2 最基礎(chǔ)的數(shù)據(jù)類型——向量
向量只需要添加一個(gè)維度就能轉(zhuǎn)換成矩陣或者數(shù)組
class(state.name) # [1] "character"字符型向量
a=state.name #現(xiàn)在a就是一個(gè)向量
dim(a) #返回NULL空值,現(xiàn)在a還沒有維度
length(a) #a這個(gè)向量有多少數(shù)據(jù)呢较店?結(jié)果有50
#為a添加一個(gè)維度
dim(a)=c(5,10) #結(jié)果a就是一個(gè)5行10列的矩陣
b=data.frame(a,state.abb) #矩陣a再加一列士八,組成一個(gè)數(shù)據(jù)框
#數(shù)據(jù)框取列可以直接b$列名,取行需要b[行號(hào),]
#數(shù)據(jù)框去掉列名用unname()
3 取子集
有時(shí)數(shù)據(jù)框中信息量太大梁呈,我們需要取其中的一部分
-
使用索引
#假設(shè)c是一個(gè)數(shù)據(jù)框 #連續(xù)提取 c1=c[c(1:10),c(1:30)] # 取10行婚度,30列 #不連續(xù)提取 c2=c[c(1,3,5),c(2,4,6)]
-
使用邏輯判斷
#利用which函數(shù) c3=c[which(c$某一列==某個(gè)值),] #返回的就是這一列是這個(gè)值的全部行 #注意:這里的判斷是用兩個(gè)=官卡,如果是一個(gè)=意思是賦值 #如果是搜索特定范圍的行 c4=c[which(c$列1>value1 & c$列1<=value1)]
-
使用subset函數(shù)【比較簡(jiǎn)便】
subset(x, subset, select ...)
首先輸入一個(gè)對(duì)象
x
陕见,可以是向量、矩陣味抖、數(shù)據(jù)框评甜;然后
subset
設(shè)置邏輯判斷,select
設(shè)置范圍c5=subset(c,c$列1>value1 & c$列1<=value1)
-
隨機(jī)抽樣:sample函數(shù)
可以設(shè)置有/無返回的隨機(jī)抽樣仔涩,可以設(shè)置樣本大小忍坷,例如彩票36選7就是無返回抽樣
sample(x, size, replace = FALSE, prob = NULL)
x是樣本:一堆元素組成的向量;
size:抽取元素個(gè)數(shù)熔脂;
replace:有無放回的抽樣
#1. 利用sample抽取向量 set.seed(123) #保證重復(fù)結(jié)果一致性 d=1:200 sort(sample(d,50,replace=T)) #設(shè)置放回抽樣佩研,排序后就會(huì)發(fā)現(xiàn)有數(shù)據(jù)重復(fù) #2.利用sample抽取數(shù)據(jù)框 c[sample(c$列1, size,replace=T/F),]
-
數(shù)據(jù)框取子集
c[1:5,] #取前5行 c[,-1:-5] #取后5列
-
變體應(yīng)用:清空行/列
c$列1 = NULL #清空c的第一列子集
4 合并
-
按行/列進(jìn)行合并(前提是相同的列/行數(shù))
cbind()、rbind()
-
合并完之后去重復(fù)
c[!duplicated(c)]
duplicated函數(shù)是取出重復(fù)部分霞揉,加感嘆號(hào)就是取相反或者使用
uniq(c)
5 翻轉(zhuǎn)
針對(duì)數(shù)據(jù)框:將所有的行和列調(diào)換t()`
-
針對(duì)向量/數(shù)據(jù)框的某一行/列:
rev()
就是reverse的意思#例如將某個(gè)數(shù)據(jù)框按行名進(jìn)行翻轉(zhuǎn)旬薯,比如women數(shù)據(jù)框【兩列:height、weight】 women[rev(rownames(women)),] #先用rownames()獲得行名 #再用rev()將行名翻轉(zhuǎn)适秩,作為下一步提取的索引 #從women中提取出來翻轉(zhuǎn)后的數(shù)據(jù)
6 修改數(shù)據(jù)框中的值
transform
函數(shù)可以方便修改數(shù)據(jù)框中任何列的值
#例如想修改women數(shù)據(jù)框中绊序,weight的值,(假設(shè))原來是斤秽荞,現(xiàn)在要改成公斤
#一種該法:【比較麻煩骤公,并且大數(shù)據(jù)量不適用】
data.frame(height=women$height,weight=women$weight/2)
#使用transform【如果不寫weight,而是用別的比如wei扬跋,那么就會(huì)在數(shù)據(jù)框最后新加一列】
transform(women,weight=women$weigh/2)
7 排序
-
sort
排序后返回的是值阶捆,默認(rèn)數(shù)字從小到大,字符串按ASCII碼【若取相反,只需要加rev() 函數(shù)】--只能用于向量排序洒试,不能直接用于數(shù)據(jù)框
但是倍奢,可以先對(duì)數(shù)據(jù)框中某一行/列進(jìn)行排序,然后根據(jù)這個(gè)索引垒棋,調(diào)整數(shù)據(jù)框
mtcars[sort(rownames(mtcars))]
#上面只是按照行名(列名也可以)進(jìn)行排序卒煞,如果想對(duì)其中某一列的數(shù)據(jù)進(jìn)行排序后,再整理數(shù)據(jù)框捕犬,用下面的order比較方便
-
order
排序后返回的是索引#按照mtcars的mpg這一列的數(shù)據(jù)進(jìn)行排序后跷坝,對(duì)數(shù)據(jù)框進(jìn)行整理 mtcars[order(mtcars$mpg),] #還支持多個(gè)條件進(jìn)行排序 mtcars[order(mtcars$mpg,mtcars$disp),] #意思就是:先對(duì)mpg進(jìn)行排序酵镜,在同一個(gè)mpg的情況下碉碉,disp小的排在前面 #要翻轉(zhuǎn)也很簡(jiǎn)單 mtcars[rev(order(mtcars$mpg)),] #或者更簡(jiǎn)單翻轉(zhuǎn) mtcars[order(-mtcars$mpg),]
8 apply系列
#例如,對(duì)worldPhones這個(gè)數(shù)據(jù)集進(jìn)行統(tǒng)計(jì)淮韭,求每一行的和垢粮、每一列的平均數(shù)
f=as.data.frame(WorldPhones)
rS=rowSums(f) #計(jì)算行的加和
cM=colMeans(f) #計(jì)算列的平均數(shù)
Sum=cbind(f,Sum=rS)
Mean=rbind(Sum,Mean=cM)
如果利用apply,就可以這樣
apply(WorldPhones,MARGIN = 1, FUN=sum) #計(jì)算行的加和
apply(WorldPhones,MARGIN = 2, FUN=mean) #計(jì)算列的平均數(shù)
#還可以新添加函數(shù)靠粪,比上面的方法拓展性更強(qiáng)【即便沒有現(xiàn)有的函數(shù)蜡吧,也可以自己創(chuàng)造】
apply(WorldPhones,MARGIN = 2, FUN=var) ##計(jì)算列的方差
apply(WorldPhones,MARGIN = 2, FUN=log) ##計(jì)算列的log
這個(gè)大家族,是R中解決循環(huán)遍歷的核心占键,包括了tapply昔善、apply、mapply畔乙、lapply君仆、sapply、rapply牲距、vapply返咱、eapply這8大成員。利用它們幾個(gè)可以方便實(shí)現(xiàn)數(shù)據(jù)循環(huán)牍鞠、分組咖摹、過濾等操作。相比于自己寫for循環(huán)难述,這種既便捷又高效
-
apply:最常使用萤晴,作為for的替代工具。對(duì)矩陣胁后、數(shù)據(jù)框硫眯、數(shù)組這樣二維以上的數(shù)據(jù),抽取其中的一個(gè)維度(行或列)進(jìn)行遍歷择同,并且加上函數(shù)計(jì)算得到結(jié)果
apply(X, MARGIN, FUN, ...) #MARGIN:1為行两入,2為列 #例如,一個(gè)矩陣 >A=matrix(1:20,ncol=4) [,1] [,2] [,3] [,4] [1,] 1 6 11 16 [2,] 2 7 12 17 [3,] 3 8 13 18 [4,] 4 9 14 19 [5,] 5 10 15 20 >apply(A,1,mean) #按行遍歷求平均值 [1] 8.5 9.5 10.5 11.5 12.5
-
lapply:(list) 對(duì)列表敲才、數(shù)據(jù)框進(jìn)行循環(huán)操作裹纳,即對(duì)X的每一個(gè)元素運(yùn)用函數(shù)择葡,結(jié)果生成一個(gè)與元素個(gè)數(shù)相同的列表。
lapply(X,FUN, ...) > B=list(a=rnorm(5,2,3), b=1:5, c=c(F,T,F,T)) $a [1] -3.060080 4.513361 2.460119 -1.414411 5.761445 $b [1] 1 2 3 4 5 $c [1] FALSE TRUE FALSE TRUE > lapply(B,length) #分別獲得每個(gè)元素的長(zhǎng)度 $a [1] 5 $b [1] 5 $c [1] 4
可以對(duì)數(shù)據(jù)框按列循環(huán)操作剃氧;但是對(duì)于矩陣敏储,它會(huì)循環(huán)計(jì)算統(tǒng)計(jì)矩陣的每個(gè)值,而不是放在一起進(jìn)行計(jì)算
C=rbind(x=6,y=c(2:4)) > C [,1] [,2] [,3] x 6 6 6 y 2 3 4 > class(C) #matrix > lapply(C,mean) #想求平均值 [[1]] [1] 6 [[2]] [1] 2 [[3]] [1] 6 [[4]] [1] 3 [[5]] [1] 6 [[6]] [1] 4 #但是如果轉(zhuǎn)換成數(shù)據(jù)框朋鞍,就可以已添,并且還能看出是按列循環(huán) #因?yàn)閘apply可以將數(shù)據(jù)框自動(dòng)按列進(jìn)行分組,然后進(jìn)行統(tǒng)計(jì) > lapply(data.frame(C),mean) $V1 [1] 4 $V2 [1] 4.5 $V3 [1] 5
-
sapply: (simple)可以理解為精簡(jiǎn)版的lapply滥酥,因?yàn)樗姆祷刂凳窍蛄?矩陣更舞,而不是列表,因此結(jié)果看起來更舒服
sapply(X, FUN, ..., simplify = TRUE, USE.NAMES =TRUE) #默認(rèn)simplify坎吻、USE.NAMES都是TRUE # simplify為array時(shí)缆蝉,會(huì)按數(shù)組進(jìn)行分組; # USE.NAMES為FALSE時(shí),不設(shè)置數(shù)據(jù)名 #因此瘦真,當(dāng)這兩者都是FALSE時(shí)刊头,結(jié)果就是lapply
> sapply(C,quantile) V1 V2 V3 0% 2 3.00 4.0 25% 3 3.75 4.5 50% 4 4.50 5.0 75% 5 5.25 5.5 100% 6 6.00 6.0 #對(duì)比下lapply與sapply > sapply(C,sum) V1 V2 V3 8 9 10 > lapply(C,sum) $V1 [1] 8 $V2 [1] 9 $V3 [1] 10 #使用apply檢查數(shù)據(jù)集中每列的屬性 > sapply(mtcars,class) mpg cyl disp hp drat wt qsec vs am "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" gear carb "numeric" "numeric"
看一下USE.NAMES設(shè)置的問題
> words=letters[1:4] > sapply(words,paste,USE.NAMES = F, 1:3) [,1] [,2] [,3] [,4] [1,] "a 1" "b 1" "c 1" "d 1" [2,] "a 2" "b 2" "c 2" "d 2" [3,] "a 3" "b 3" "c 3" "d 3" > sapply(words,paste,USE.NAMES = T, 1:3) a b c d [1,] "a 1" "b 1" "c 1" "d 1" [2,] "a 2" "b 2" "c 2" "d 2" [3,] "a 3" "b 3" "c 3" "d 3"
-
vapply: sapply基礎(chǔ)上可以設(shè)定返回值
vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE) # X為列表或數(shù)據(jù)框 # FUN.VALUE是新增內(nèi)容,設(shè)定了返回值的行名row.names;不設(shè)置時(shí)诸尽,為默認(rèn)的索引值
-
tapply: 分組統(tǒng)計(jì)使用
tapply(X, INDEX, FUN, ..., simplify = TRUE) #通過index將數(shù)據(jù)集X分組,index可以是多個(gè)的集合 #例如原杂,通過mtcars數(shù)據(jù)集中的cyl氣缸數(shù)對(duì)mpg耗油量進(jìn)行分組,并且計(jì)算平均值 > tapply(mtcars$mpg,mtcars$cyl,mean) 4 6 8 26.66364 19.74286 15.10000 #又如:統(tǒng)計(jì)不同年齡的吸煙人數(shù) > age=c(24,26,57,13,56) > smoke=c("F","F","T","F","T") > tapply(age,smoke, sum) F T 63 113
-
mapply: 將函數(shù) FUN 依次應(yīng)用在第一個(gè)元素您机、第二個(gè)元素...上
mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE) #例如穿肄,循環(huán)比對(duì)每一列的數(shù)值大小,取最小值 > x=1:6 > y=8:-3 > z=c(1,4,8,-4,1,6) > mapply(min,x,y,z) [1] 1 2 1 -4 -1 -2
9 數(shù)據(jù)優(yōu)化
目的為了向數(shù)據(jù)中心靠攏往产,減小數(shù)據(jù)之間的差別被碗。一般數(shù)據(jù)集都會(huì)有n列,并且各列之間有的單位都不同仿村,顯示的數(shù)字有的大有的小锐朴,如果直接拿來用,基本看不差什么差別蔼囊。因此需要中心化和標(biāo)準(zhǔn)化焚志,也就是對(duì)每一列進(jìn)行等比例的縮小【因?yàn)楸容^時(shí)是對(duì)各列內(nèi)部進(jìn)行比較得到的結(jié)果,因此一列內(nèi)同時(shí)縮小并不影響畏鼓,但是好處就是數(shù)據(jù)大小接近了其他列】
- 中心化:數(shù)據(jù)集的各個(gè)數(shù)據(jù)減去均值
- 標(biāo)準(zhǔn)化:中心化后的數(shù)據(jù)除以標(biāo)準(zhǔn)差
#比如現(xiàn)在有一組數(shù)據(jù)酱酬,想看看他們之間的差別
X=c(1,3,6,8,3)
> X-mean(X) #中心化的結(jié)果,發(fā)現(xiàn)差別還是比較大云矫,如3.8與-3.2
[1] -3.2 -1.2 1.8 3.8 -1.2
> (X-mean(X))/sd(X) #進(jìn)行標(biāo)準(zhǔn)化膳沽,可以看到數(shù)據(jù)比較接近了
[1] -1.153200 -0.432450 0.648675 1.369425 -0.432450
上面是原理,當(dāng)然實(shí)際用的時(shí)候,可以直接使用scale函數(shù)
scale(x, center = TRUE, scale = TRUE)
#center = TRUE進(jìn)行中心化
#scale = TRUE 進(jìn)行標(biāo)準(zhǔn)化
> scale(X)
[,1]
[1,] -1.153200
[2,] -0.432450
[3,] 0.648675
[4,] 1.369425
[5,] -0.432450
attr(,"scaled:center")
[1] 4.2
attr(,"scaled:scale")
[1] 2.774887
一個(gè)實(shí)例數(shù)據(jù)集mtcars的處理前后
#mtcars是一個(gè)數(shù)據(jù)框挑社,首先轉(zhuǎn)換成矩陣陨界,然后畫熱圖
> y=as.matrix(mtcars)
> heatmap(y)
> y1=scale(y)
> heatmap(y1)
10 數(shù)據(jù)框變形——reshape2
install.packages("reshape2")
library(reshape2)
#原理想象一下煉鋼的過程:將數(shù)據(jù)融化痛阻,然后注入模具菌瘪,就能得到想要的形狀
#melt函數(shù)將寬數(shù)據(jù)變成長(zhǎng)數(shù)據(jù),cast將長(zhǎng)數(shù)據(jù)變?yōu)閷挃?shù)據(jù)
> help(package="reshape2") #查看包的幫助信息
# 先看一下其中的melt.data.frame阱当,幫助信息中有實(shí)例數(shù)據(jù)俏扩,幫助理解
> airquality
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
#先將列名改為小寫,就為了輸入方便
> names(airquality) = tolower(names(airquality) )
> airquality
ozone solar.r wind temp month day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
# 再用melt融合數(shù)據(jù)弊添,融合后的數(shù)據(jù)變成了3列录淡,每一行都是唯一的;其中variable是因子表箭,包含了之前的列名
> head(melt(airquality))
variable value
1 ozone 41
2 ozone 36
3 ozone 12
4 ozone 18
5 ozone NA
6 ozone 28
# variable其中包括了month赁咙、day钮莲,讓他們當(dāng)成id免钻,其余的"ozone" "solar.r" "wind" "temp" 才作為觀測(cè)名
> aq1 = melt(airquality,id=c("month","day"))
> head(aq1)
month day variable value
1 5 1 ozone 41
2 5 2 ozone 36
3 5 3 ozone 12
4 5 4 ozone 18
5 5 5 ozone NA
6 5 6 ozone 28
#然后可以進(jìn)行重鑄cast:reshape2包在reshape1的基礎(chǔ)上將cast又重新細(xì)分,dcast處理數(shù)據(jù)框崔拥,acast返回向量极舔、矩陣或數(shù)組
#dcast讀取melt的結(jié)果后,根據(jù)提供的公式來融合數(shù)據(jù)链瓦。其中的formula參數(shù)就是融合后的數(shù)據(jù)格式【formula中使用波浪線~拆魏,表示二者相關(guān)聯(lián),但不是相等】
# 我們這里融合后的數(shù)據(jù)有4列:month慈俯、day渤刃、variable(其中又包括了4個(gè)變量)、value
> aqcast=dcast(aq1, month ~ variable, fun.aggregate = mean, na.rm=T)
#想看month和variable之間的關(guān)系贴膘,那么一個(gè)月有許多天卖子,days不指定的話,R不知道怎么統(tǒng)計(jì)刑峡,于是我們可以使用fun.aggregate這個(gè)函數(shù)洋闽,指定一個(gè)統(tǒng)計(jì)函數(shù),比如sum/mean等突梦,再用na.rm去掉缺失值诫舅,就得到了每個(gè)月這四個(gè)變量的平均值
> head(aqcast)
month ozone solar.r wind temp
1 5 23.61538 181.2963 11.622581 65.54839
2 6 29.44444 190.1667 10.266667 79.10000
3 7 59.11538 216.4839 8.941935 83.90323
4 8 59.96154 171.8571 8.793548 83.96774
5 9 31.44828 167.4333 10.180000 76.90000
11 tidyr
tidy整潔的,相比這個(gè)包的數(shù)據(jù)一定要求比較整潔的tidy data
什么才算整潔的數(shù)據(jù)呢宫患?
- 每一列代表一個(gè)變量
- 每一行代表一個(gè)觀測(cè)值
- 一個(gè)觀測(cè)和一個(gè)變量確定唯一的值
- 【如果存在相同行名或列名就不算】
四個(gè)重要的函數(shù):
- gather:寬數(shù)據(jù)轉(zhuǎn)為長(zhǎng)數(shù)據(jù)【作用等于reshape2中的melt函數(shù)】
- spread:長(zhǎng)數(shù)據(jù)轉(zhuǎn)位寬數(shù)據(jù)【作用等于reshape2中的cast函數(shù)】
- unite:多列合并為一列
- separate:一列分為多列
使用mtcars數(shù)據(jù)集刊懈,符合tidy data的要求
#取部分mtcars數(shù)據(jù)(前6行,前4列)
> mdata = mtcars[1:6,1:4] #發(fā)現(xiàn)car names是以行名存在的,我們?cè)趍data的基礎(chǔ)上新加一列names虚汛,賦值car names当宴。也就是將mdata和新建的行名變量合并在一起,組成一個(gè)新的數(shù)據(jù)框
> mdata=data.frame(names=rownames(mdata),mdata)
> mdata
names mpg cyl disp hp
Mazda RX4 Mazda RX4 21.0 6 160 110
Mazda RX4 Wag Mazda RX4 Wag 21.0 6 160 110
Datsun 710 Datsun 710 22.8 4 108 93
Hornet 4 Drive Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout Hornet Sportabout 18.7 8 360 175
Valiant Valiant 18.1 6 225 105
## 寬數(shù)據(jù)得到了泽疆,接下來使用gather
#gather(data, key = "key", value = "value"户矢,...)
#data:像mdata這樣的數(shù)據(jù)框
#key、value:處理后的
#...指定對(duì)哪些變量進(jìn)行處理
> gdata=gather(mdata,key = "Key", value = "Value", mpg,cyl, disp,hp)
#這里的列名可以用列的編號(hào)代替殉疼,比如:mpg,cyl, disp,hp 對(duì)應(yīng)2:4
names Key Value
1 Mazda RX4 mpg 21.0
2 Mazda RX4 Wag mpg 21.0
3 Datsun 710 mpg 22.8
4 Hornet 4 Drive mpg 21.4
5 Hornet Sportabout mpg 18.7
6 Valiant mpg 18.1
7 Mazda RX4 cyl 6.0
8 Mazda RX4 Wag cyl 6.0
9 Datsun 710 cyl 4.0
10 Hornet 4 Drive cyl 6.0
11 Hornet Sportabout cyl 8.0
12 Valiant cyl 6.0
13 Mazda RX4 disp 160.0
14 Mazda RX4 Wag disp 160.0
15 Datsun 710 disp 108.0
16 Hornet 4 Drive disp 258.0
17 Hornet Sportabout disp 360.0
18 Valiant disp 225.0
19 Mazda RX4 hp 110.0
20 Mazda RX4 Wag hp 110.0
21 Datsun 710 hp 93.0
22 Hornet 4 Drive hp 110.0
23 Hornet Sportabout hp 175.0
24 Valiant hp 105.0
## 使用spread又能將gdata打回原形
> spread(gdata,key = "Key", value = "Value")
## 使用seperate分隔
> tmp1=data.frame(x=c(NA,"1.b-c","2-c","3-d"))
> tmp2=separate(tmp1, col=x, into=c("X","Y"),sep="-")
X Y
1 <NA> <NA>
2 1.b c
3 2 c
4 3 d
## 使用unite連接
#先輸入要操作的數(shù)據(jù)框tmp2梯浪,然后設(shè)定拼接后的列名col,然后指定拼接tmp2中的哪些列瓢娜,最后指定sep分隔符
> unite(tmp2,col="XY",X,Y,sep="-")
XY
1 NA-NA
2 1.b-c
3 2-c
4 3-d
12 dplyr
> ls("package:dplyr") #查看一下這個(gè)包中的函數(shù)(共245個(gè))
> help(package="dplyr") #查看包的幫助信息
## filter過濾功能
> dplyr::filter(iris,iris$Sepal.Width>4)
#這里調(diào)用函數(shù)的方式和一般的有點(diǎn)不太一樣挂洛,因?yàn)閐plyr中的函數(shù)太多,很大可能和其他包的函數(shù)名重合眠砾,因此使用dplyr::避免這個(gè)問題
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.7 4.4 1.5 0.4 setosa
2 5.2 4.1 1.5 0.1 setosa
3 5.5 4.2 1.4 0.2 setosa
## distinct去除重復(fù)虏劲,等于linux中uniq功能
> tmp3=iris[1:3,] #構(gòu)建兩個(gè)之間有重復(fù)行的數(shù)據(jù)tmp3、tmp4
> tmp4=iris[1:4,]
> dplyr::distinct(rbind(tmp3,tmp4)) #先將tmp3褒颈、4按行合并起來柒巫,再去重
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
##slice:切片
> dplyr::slice(iris,3:6) #取出3-6行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 4.7 3.2 1.3 0.2 setosa
2 4.6 3.1 1.5 0.2 setosa
3 5.0 3.6 1.4 0.2 setosa
4 5.4 3.9 1.7 0.4 setosa
##sample_n:隨機(jī)取樣
> dplyr::sample_n(iris,5)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
34 5.5 4.2 1.4 0.2 setosa
57 6.3 3.3 4.7 1.6 versicolor
91 5.5 2.6 4.4 1.2 versicolor
52 6.4 3.2 4.5 1.5 versicolor
17 5.4 3.9 1.3 0.4 setosa
##sample_frac: 按比例取樣
> dplyr::sample_frac(iris,0.02)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
3 5.5 3.5 1.3 0.2 setosa
10 5.7 2.8 4.1 1.3 versicolor
6 5.9 3.0 4.2 1.5 versicolor
##arrange:排序【這里對(duì)Sepal.Width這一列進(jìn)行排序】
> head(dplyr::arrange(iris,iris$Sepal.Width))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.0 2.0 3.5 1.0 versicolor
2 6.0 2.2 4.0 1.0 versicolor
3 6.2 2.2 4.5 1.5 versicolor
4 6.0 2.2 5.0 1.5 virginica
5 4.5 2.3 1.3 0.3 setosa
6 5.5 2.3 4.0 1.3 versicolor
#要逆向排序(從大到小)
> head(dplyr::arrange(iris,desc(iris$Sepal.Width)))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.7 4.4 1.5 0.4 setosa
2 5.5 4.2 1.4 0.2 setosa
3 5.2 4.1 1.5 0.1 setosa
4 5.8 4.0 1.2 0.2 setosa
5 5.4 3.9 1.7 0.4 setosa
6 5.4 3.9 1.3 0.4 setosa
##取子集select谷丸,可以直接根據(jù)列名選擇堡掏,可以根據(jù)各種條件【如:以某些字符開頭、結(jié)尾刨疼、包含固定字符等】泉唁,相比subset函數(shù)更強(qiáng)大
> select(iris,starts_with("Petal")) #取以xx開頭的列
> select(iris,ends_with("Width")) #取以xx結(jié)尾的列
> select(iris,Species,everything()) #將原來的最后一列Species移到第一列
> select(df,X4:X6) #選擇df數(shù)據(jù)框X4-X6這些列
#當(dāng)然需要注意!X4-X6這中間可能不是按順序編號(hào)的揩慕,可能X4和X6之間還有X1亭畜、X7、X9等等迎卤,那么如何只選出X4拴鸵、X5、X6真正的X4-X6呢止吐?
> select(df, num_range("X",4:6)) #給出了上面話的答案
> select(iris,-starts_with("Petal")) #反選
> select(mtcars, .data$cyl)#當(dāng)數(shù)據(jù)集名字不想多次重復(fù)宝踪,可以用.data代替
> select(mtcars, .data$mpg : .data$disp) #使用.data多選幾列
> select(iris,petal_length=Petal.Length) #對(duì)列重命名,并且結(jié)果只保留重命名的這一列
> rename(iris, petal_length = Petal.Length) # 也是重命名碍扔,但是所有列都保留
#想要重命名多列瘩燥,可以這樣:
> vars <- c(var1 = "cyl", var2 ="am") #先命名好,比如要把cyl更換為var1
> select(mtcars, !!vars) #與上面select效果一致
> rename(mtcars, !!vars) #與上面rename效果一致
##統(tǒng)計(jì)函數(shù)summarise
> summarise(mtcars, sum=sum(mpg))
sum
1 642.9
#還包括summarise_all等
> summarise_all(mtcars, sum)
mpg cyl disp hp drat wt qsec vs am gear carb
1 642.9 198 7383.1 4694 115.09 102.952 571.16 14 13 118 90
##分組:group_by
> dplyr::group_by(iris,Species) #對(duì)iris數(shù)據(jù)集按照Species進(jìn)行分組
# A tibble: 150 x 5
# Groups: Species [3]
##添加新的變量mutate
> dplyr::mutate(iris, var1=iris$Sepal.Length+iris$Petal.Length) %>% head()
Sepal.Length Sepal.Width Petal.Length Petal.Width Species var1
1 5.1 3.5 1.4 0.2 setosa 6.5
2 4.9 3.0 1.4 0.2 setosa 6.3
3 4.7 3.2 1.3 0.2 setosa 6.0
4 4.6 3.1 1.5 0.2 setosa 6.1
5 5.0 3.6 1.4 0.2 setosa 6.4
6 5.4 3.9 1.7 0.4 setosa 7.1
########################################################################## 上面都是對(duì)一個(gè)數(shù)據(jù)框進(jìn)行操作不同,如何對(duì)兩個(gè)操作呢厉膀?###########
###############################################################
#先造兩個(gè)數(shù)據(jù)框
a=data.frame(m1=c("a","b","c"),m2=c(2,3,4));a
b=data.frame(m1=c("a","b","z"),m3=c(T,T,T));b
###關(guān)于集合的操作
#先進(jìn)行左連接【left】【以a的m1為依據(jù)溶耘,但是b中m1沒有c,所以它的第三行m3是NA】
> dplyr::left_join(a,b,by="m1")
m1 m2 m3
1 a 2 TRUE
2 b 3 TRUE
3 c 4 NA
#再進(jìn)行右連接【right】
> dplyr::right_join(a,b,by="m1")
m1 m2 m3
1 a 2 TRUE
2 b 3 TRUE
3 z NA TRUE
#內(nèi)連接【inner取交集】
> dplyr::inner_join(a,b,by="m1")
m1 m2 m3
1 a 2 TRUE
2 b 3 TRUE
#全連接【full取并集】
> dplyr::full_join(a,b,by="m1")
m1 m2 m3
1 a 2 TRUE
2 b 3 TRUE
3 c 4 NA
4 z NA TRUE
#半連接【semi】根據(jù)右側(cè)表b的內(nèi)容對(duì)左側(cè)表a進(jìn)行過濾服鹅,輸出交集
#反連接【anti】也是根據(jù)右側(cè)表b凳兵,但輸出a、b的補(bǔ)集
###幾個(gè)數(shù)據(jù)集的合并【其實(shí)原理也是利用了集合】
#先造兩個(gè)數(shù)據(jù)集【他們之間是有交叉的行的】
> one=mutate(mtcars,Name=rownames(mtcars)) %>% slice(1:15)
> two=mutate(mtcars,Name=rownames(mtcars)) %>% slice(5:20)
> intersect(one,two)#取交集
> dplyr::union(one,two) #取并集
> setdiff(one,two) #求one的補(bǔ)集【相對(duì)于two的補(bǔ)集】企软;交換下順序就是求two的補(bǔ)集了
13 鏈?zhǔn)讲僮鞣?/h3>
相當(dāng)于Linux中的管道符庐扫,R中使用%>%,實(shí)現(xiàn)一個(gè)函數(shù)的輸出傳給下一個(gè)函數(shù)仗哨,作為下一個(gè)的輸入
使用ctrl + shift + M方便打出
#例如:取出第3-6行
> head(mtcars) %>% tail(3)
##分組加統(tǒng)計(jì):group_by + summarise
> iris %>% group_by(Species) %>% summarise(total=sum(Petal.Length)) %>% arrange()
# A tibble: 3 x 2 可以看到分成了setosa形庭、versicolor、virginica 三組,另外每一組的Petal.Length總數(shù)也統(tǒng)計(jì)出來厌漂,最后使用arrange進(jìn)行排序
Species total
<fct> <dbl>
1 setosa 73.1
2 versicolor 213
3 virginica 278.
相當(dāng)于Linux中的管道符庐扫,R中使用%>%,實(shí)現(xiàn)一個(gè)函數(shù)的輸出傳給下一個(gè)函數(shù)仗哨,作為下一個(gè)的輸入
使用ctrl + shift + M方便打出
#例如:取出第3-6行
> head(mtcars) %>% tail(3)
##分組加統(tǒng)計(jì):group_by + summarise
> iris %>% group_by(Species) %>% summarise(total=sum(Petal.Length)) %>% arrange()
# A tibble: 3 x 2 可以看到分成了setosa形庭、versicolor、virginica 三組,另外每一組的Petal.Length總數(shù)也統(tǒng)計(jì)出來厌漂,最后使用arrange進(jìn)行排序
Species total
<fct> <dbl>
1 setosa 73.1
2 versicolor 213
3 virginica 278.
歡迎關(guān)注我們的公眾號(hào)~_~
我們是兩個(gè)農(nóng)轉(zhuǎn)生信的小碩萨醒,打造生信星球,想讓它成為一個(gè)不拽術(shù)語苇倡、通俗易懂的生信知識(shí)平臺(tái)富纸。需要幫助或提出意見請(qǐng)后臺(tái)留言或發(fā)送郵件到Bioplanet520@outlook.com