R數(shù)據(jù)格式轉(zhuǎn)換

劉小澤寫于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大家族
  • 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)
中心化、標(biāo)準(zhǔn)化

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. 

歡迎關(guān)注我們的公眾號(hào)~_~  
我們是兩個(gè)農(nóng)轉(zhuǎn)生信的小碩萨醒,打造生信星球,想讓它成為一個(gè)不拽術(shù)語苇倡、通俗易懂的生信知識(shí)平臺(tái)富纸。需要幫助或提出意見請(qǐng)后臺(tái)留言或發(fā)送郵件到Bioplanet520@outlook.com

Welcome to our bioinfoplanet!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市旨椒,隨后出現(xiàn)的幾起案子晓褪,更是在濱河造成了極大的恐慌,老刑警劉巖钩乍,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辞州,死亡現(xiàn)場(chǎng)離奇詭異怔锌,居然都是意外死亡寥粹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門埃元,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涝涤,“玉大人,你說我怎么就攤上這事岛杀±” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵类嗤,是天一觀的道長(zhǎng)糊肠。 經(jīng)常有香客問我,道長(zhǎng)遗锣,這世上最難降的妖魔是什么货裹? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮精偿,結(jié)果婚禮上弧圆,老公的妹妹穿的比我還像新娘赋兵。我一直安慰自己,他們只是感情好搔预,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布霹期。 她就那樣靜靜地躺著,像睡著了一般拯田。 火紅的嫁衣襯著肌膚如雪历造。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天船庇,我揣著相機(jī)與錄音帕膜,去河邊找鬼。 笑死溢十,一個(gè)胖子當(dāng)著我的面吹牛垮刹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播张弛,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼荒典,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了吞鸭?” 一聲冷哼從身側(cè)響起寺董,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刻剥,沒想到半個(gè)月后遮咖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡造虏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年御吞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漓藕。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陶珠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出享钞,到底是詐尸還是另有隱情揍诽,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布栗竖,位于F島的核電站暑脆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狐肢。R本人自食惡果不足惜添吗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望处坪。 院中可真熱鬧根资,春花似錦架专、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱叭。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間德谅,已是汗流浹背婚瓜。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工稍途, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留着逐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓漆际,卻偏偏與公主長(zhǎng)得像淆珊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奸汇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容