数据处理之——plyr
本文主要介绍如何利用R中的plyr包对数据进行处理。plyr是R中做数据处理和加工的包,它可以用来做类似EXCEL数据透视表的操作。 split-apply-combinesplit-apply-combine是plyr包的基本思想,首先把大的数据集按照一定的规则对数据进行拆分(split),然后对每个拆分后的小数据集应用同一函数进行处理(apply),最后把处理后的结果汇总起来形成最终的结果(combine)。 -- 对数据框的子集拟合相同的模型 -- 快速计算每个分组的描述性统计量 -- 实现分组进行数据标准化 可能你会说,上面说的这些我用R的基本函数split以及apply函数簇也可以实现啊。是的,直接用R里面的函数也能实现相应的功能,但是用plyr实现起来会更容易,它的优势主要体现在以下几方面: -- 完全一致的名称、参数和输出 -- 更方便地并行化实现 -- 清楚地定义了输入和输出数据类型 -- 内置错误恢复和提供信息错误消息 -- 在所有转换中的标签会保留 当你熟悉了plyr的操作以后,你会发现它能在特定的情况下大大提高我们的编程效率,编写出代码更简洁。而且在大多数情况下,用plyr编写的程序代码比用R内置函数编写的运算速度要快。下面我们把plyr包中的函数分为主函数和辅助函数来分别介绍。 主函数**ply函数簇 主函数为**ply函数簇,**表示输入输出数据类型: 其中字母a表示数组,字母d表示数据框,字母l表示列表,下划线_表示函数并无返回值。 adply()表示输入为数组,输出为数据框的函数 ddply()表示输入为数据框,输出为数据框的函数 dlply()表示输入为数组,输出为列表的函数 l_ply()表示输入为列表,无返回值的函数 函数用法
了解了**ply函数族的含义,我们再来看看上面三个函数簇的具体调用参数,.data是输入待处理的数据集,.variables与.margins描述了怎么去划分数据,.fun表示对划分后的数据集进行处理的函数,.progress可以用来显示程序的进度,none表示不显示。 如何划分数据我们来用图例来做一下说明: 数组用.margins按照维度来划分,比如,对于矩阵,1表示按行划分,2表示按列划分,c(1,2)表示单个数组元素。三维情况如下: 简单示例,采用plyr求球员的参赛场次,场均得分和助攻以及效率值 myfun <- function(x){ ?withx,{count = nrow) ? ? ? ? ?mpts meanptsmast astper sum((pts+astrebstlblk)-(fga-fgmftaftm)-tov)/data.framecount=count,mptsmpts,0);">mastmast,0);">perper) ? ? ? ? ?})} ## ? player count ? ? mpts ? ? ?mast ? ? ?per ## 1 ? 保罗 ? ?74 19.54054 ?9.972973 24.75676 ## 2 ? 康利 ? ?56 15.30357 ?6.107143 16.46429 ## 3 ? 库里 ? ?79 30.06329 ?6.670886 30.68354 ## 4 ? 欧文 ? ?53 19.64151 ?4.716981 16.81132 ## 5 ? 威少 ? ?80 23.47500 10.425000 28.53750 ## 6 ? 沃尔 ? ?77 19.88312 10.246753 22.54545 初看起来plyr包所具备的功能并不是很强,我们用R自带的常规函数也能实现嘛。好吧,下面我就一个简单的例子来展示plyr的便捷之处。 还是用pgdat数据(该数据集见微信公众号:案例数据),我们想知道每个控卫得分与上场时间的关系,这里采用简单线性回归,之后提取回归的截距和斜率值。 首先我们自定义线性回归函数: lmfit ) { ? ?lm~min,0);">data)} 如果用最基本的循环: players uniquepgdat$) ## ? ? ? ?Intercept ? ? slope ## 欧文 ?-6.8012949 0.8417229 ## 保罗 ? 0.9652118 0.5670686 ## 威少 -10.4073140 0.9860259 ## 康利 ?-0.7273213 0.5118187 ## 库里 ? 6.7341919 0.6813304 ## 沃尔 ?-6.7297766 0.7363251 如果用自带的apply的函数: pieces splitlist)) 如果用plyr: library(plyr) 孰优孰劣,一比便知。 辅助函数m_ply() nc(10,100,153);">50mean5,153);">10sd1,153);">2,135);">))data ## ? ? n mean sd ## 1 ?10 ? ?5 ?1 ## 2 100 ? ?5 ?2 ## 3 ?50 ? 10 ?1 mlplydata,0);">rnorm) arrange() 排序arrangedat1,0);">desc)) # 按效率值降序排列 ## ? player count ? ? mpts ? ? ?mast ? ? ?per ## 1 ? 库里 ? ?79 30.06329 ?6.670886 30.68354 ## 2 ? 威少 ? ?80 23.47500 10.425000 28.53750 ## 3 ? 保罗 ? ?74 19.54054 ?9.972973 24.75676 ## 4 ? 沃尔 ? ?77 19.88312 10.246753 22.54545 ## 5 ? 欧文 ? ?53 19.64151 ?4.716981 16.81132 ## 6 ? 康利 ? ?56 15.30357 ?6.107143 16.46429 mast) # 按平均助攻升序排列 ## ? player count ? ? mpts ? ? ?mast ? ? ?per ## 1 ? 欧文 ? ?53 19.64151 ?4.716981 16.81132 ## 2 ? 康利 ? ?56 15.30357 ?6.107143 16.46429 ## 3 ? 库里 ? ?79 30.06329 ?6.670886 30.68354 ## 4 ? 保罗 ? ?74 19.54054 ?9.972973 24.75676 ## 5 ? 沃尔 ? ?77 19.88312 10.246753 22.54545 ## 6 ? 威少 ? ?80 23.47500 10.425000 28.53750 desc表示倒序 count"player"# 统计参赛场次 ## ? player freq ## 1 ? 保罗 ? 74 ## 2 ? 康利 ? 56 ## 3 ? 库里 ? 79 ## 4 ? 欧文 ? 53 ## 5 ? 威少 ? 80 ## 6 ? 沃尔 ? 77 each()整合多个函数并输出结果 max,135);">)(df)) ## ? player ? ? mean max ?sum ## 1 ? 保罗 19.54054 ?40 1446 ## 2 ? 康利 15.30357 ?27 ?857 ## 3 ? 库里 30.06329 ?53 2375 ## 4 ? 欧文 19.64151 ?35 1041 ## 5 ? 威少 23.47500 ?48 1878 ## 6 ? 沃尔 19.88312 ?41 1531 colwise()对多列使用相同函数并输出结果 colwisepts,0);">ast,0);">stl,135);">))) ## ? player pts ast stl blk ## 1 ? 保罗 ?40 ?19 ? 7 ? 1 ## 2 ? 康利 ?27 ?11 ? 4 ? 2 ## 3 ? 库里 ?53 ?15 ? 5 ? 2 ## 4 ? 欧文 ?35 ?12 ? 4 ? 2 ## 5 ? 威少 ?48 ?19 ? 6 ? 2 ## 6 ? 沃尔 ?41 ?19 ? 7 ? 5 join()jion相关的函数在dplyr中有升级,并且封装得更好,这部分内容待到下期介绍dplyr的使用时再做详细介绍。 ?本文来自№→★飞刀的微信公共帐号“数据挖掘与R语言”,用微信添加数据挖掘与R语言公众号,即可订阅。转载必须保留作者、公共帐号信息。 长按识别图中二维码? (编辑:天津站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |