天天看點

R語言的資料轉換: split – apply – combine 模式

在資料分析中,有許多問題可以由類似的類型和方法步驟解決,可稱之為模式,設計模式或者分析模式。下面要讨論的是資料轉換的一個常用模式:split – apply – combine。其解決之道,在R語言中,有3種方式:

(1) for 顯式循環,但是這種方式的缺點也很明顯,代碼長,易出錯,也難以并行化;

(2) 拜R語言的向量計算特點所賜,在R當中,大多數問題不需要用顯示循環方式,而代之以base包中的apply函數族及其它的一些函數,直接對向量,數組,清單和資料框實作循環的操作。

(3) Hadley Wickham大神覺得apply族還是不夠簡潔,是以開發了plyr包,以更少的代碼來解決split – apply – combine問題。

1 split – apply – combine模式

大型資料集通常是高度結構化的,結構使得我們可以按不同的方式分組,有時候我們需要關注單個組的資料片斷,有時需要聚合不同組内的資訊,并互相比較。

是以對資料的轉換,可以采用split – apply – combine模式來進行處理:

split:把要處理的資料分割成小片斷;

apply:對每個小片斷獨立進行操作;

combine:把片斷重新組合。

利用這種模式解決問題在很多資料分析或程式設計問題中都會出現:

Python當中,是map( ),filter( ),reduce( );

Google 有MapReduce;

R 當中是split( ),*apply( ),aggregate( )…,以及plyr包。

在本篇(上)中,介紹R的base包中給出的解決split – apply – combine模式的一些函數,在本篇(下)中,介紹plyr包

2 分劃:split函數

    在R當中,split這個步驟是由split( ),subset( )等等函數完成的。

    下面主要介紹split這個函數。

    函數split()可以按照分組因子,把向量,矩陣和資料框進行适當的分組。它的傳回值是一個清單,代表分組變量每個水準的觀測。這個清單可以使用sapply(),lapply()進行處理(apply – combine步驟),得到問題的最終結果。

    split( )的基本用法是:group <- split(X,f)

    其中X 是待分組的向量,矩陣或資料框。f是分組因子。

##例1:對向量分組

> library(MASS)

#使用Cars93資料集,利用其中的Origin變量(兩個水準),對Price變量分組

> g<-split(Cars93$Price,Cars93$Origin)

#分組結果是個清單:

$USA

 [1] 15.7 20.8 23.7 26.3 34.7 40.1 13.4 11.4 15.1 15.9 16.3 16.6 18.8 38.0

[15] 18.4 15.8 29.5 9.2 11.3 13.3 19.0 15.6 25.8 12.2 19.3 7.4 10.1 11.3

[29] 15.9 14.0 19.9 20.2 20.9 34.3 36.1 14.1 14.9 13.5 16.3 19.5 20.7 14.4

[43] 9.0 11.1 17.7 18.5 24.4 11.1

$`non-USA`

 [1] 15.9 33.9 29.1 37.7 30.0 8.4 12.5 19.8 12.1 17.5 8.0 10.0 10.0 13.9

[15] 47.9 28.0 35.2 8.3 11.6 16.5 19.1 32.5 31.9 61.9 10.3 26.1 11.8 15.7

[29] 19.1 21.5 28.7 8.4 10.9 19.5 8.6 9.8 18.4 18.2 22.7 9.1 19.7 20.0

[43] 23.3 22.7 26.7

#計算組的長度群組内均值

> sapply(g,length)

    USA non-USA

     48 45

> sapply(g,mean)

     USA non-USA

18.57292 20.50889

#用lapply也可以,傳回值是清單

> lapply(g,mean)

$USA

[1] 18.57292

$`non-USA`

[1] 20.50889

#例2:對矩陣分組(按列)

> m<-cbind(x=1:10,y=11:20)

> split(m,col(m))

$`1`

 [1] 1 2 3 4 5 6 7 8 9 10

$`2`

 [1] 11 12 13 14 15 16 17 18 19 20

##例3:對資料框進行分組

#還是利用Cars93,它就是個資料框

g<-split(Cars93,Cars93$Origin)

#分組結果

> summary(g)

        Length Class Mode

USA 27 data.frame list

non-USA 27 data.frame list

split還有一個逆函數,unsplit,可以讓分組完好如初。

在base包裡和split功能接近的函數有cut(對屬性資料分劃),strsplit(對字元串分劃)以及

subset(對向量,矩陣或資料框按給定條件取子集)等。

轉自http://site.douban.com/182577/widget/notes/10567181/note/245088040/ 

繼續閱讀