R语言的数据转换: split – apply – combine 模式

来源:互联网 发布:mac桌面拷贝文件到u盘 编辑:程序博客网 时间:2024/06/05 18:25
在数据分析中,有许多问题可以由类似的类型和方法步骤解决,可称之为模式,设计模式或者分析模式。下面要讨论的是数据转换的一个常用模式: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/ 

0 0
原创粉丝点击