0. 引言
假设有一组气象数据,包括观测站点、观测日期、观测值和站点所属的省份,分别记为id.site、id.device、obs.date、obs.value、state,存储在数据框records中。
问题:求每个省每天所有站点的观测平均值
这个问题如果手写for循环来解决的话非常低效,需要结合R数据对象的向量特性,利用向量计算来解决。问题是要把数据分解为每个省,再分解为每天,然后求所有站点的观测平均值。
apply和tapply能够对数据进行分组处理,但是只能用于vector/array,apply只能从数据维度来对数据分组处理,tapply则指能对单个变量进行分组。这两个函数都比较局限。
1. plyr包
plyr包属于R base packages。该包实现了
①数据切分->②分块处理->③结果合并
这种处理逻辑,the split-apply-combine paradigm for R。首先对数据进行一个或多个变量/维度的数据分割,再对分割的各个子数据集进行一种或多种处理(在一个或多个指定字段上),最后汇聚各个子集的结果作为返回值。plyr包的优势在于其处理逻辑完整清晰,可以是单种加工处理也可以是多种,支持的待处理数据类型多,而且返回值有多种可指定的类型。对于0.引言中的问题,利用plyr包,只需要指定数据切分的省份和观测日期两个变量,和均值函数,即可得到想要的结果。
1.1 plyr包的函数
核心函数说明了该包可适用的数据处理类型和可提供的返回值类型。核心函数的命名规则如下:
XXply
第一个字母表示函数应用的对象类型,第二个字母表示函数返回值的对象类型,
字母取值有:
a: array_: nothing
包中核心函数如下,容易知道各个函数的适应对象类型和返回值类型,例如laply的参数对象为list,返回值为array;m_ply的参数对象为multiple inputs, 忽略返回值(无返回值)
aaply adply alply a_ply
daply ddply dlply d_ply
laply ldply llply l_ply
maply mdply mlply m_ply
1.2 ddply函数——核心函数使用示例
以ddply函数说明plyr的功能。
ddply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL)
上述式子中点号没有特殊含义,各个参数的含义如下:
.data: 待处理的数据框
.variables: 用来分割数据框的一个或多个列元素。此元素可以不是名义变量。当有多个变量时,按照各个变量的顺序依次递归对数据进行分组
fun: 施加在各个数据子集上的函数
...: 该函数的可选参数
(其他参数查阅R帮助文档)
对于0.引言中的问题,使用ddply解决如下
result<-ddply(records, .(state,obs.date), mean)
summarise(.data, ...)
.data 待处理的数据框
... 对数据框施加的函数,格式为var=value,其中var为计算结果,value为计算表达式。可以有多组函数,即进行多重处理。
eg. 求数据框baseball的时间跨度、球队数
summarise(baseball, duration = max(year) - min(year),
nteams = length(unique(team)))
ddply中使用summary
#求各个省份每天各个站点观测的平均值、最大值和最小值的差值
ddply(records, .(state,obs.date),summarise, daily.mean=mean(obs.value),daily.diff=max(obs.value)-miin(obs.value))
2. 后记
plyr包对于R中数据的分块处理非常好用,相对于xapply系列函数,有更为宽泛的数据适用和数据分割能力,也能对分块数据进行多重处理