R语言reshape2包处理数据2021.3.6

Python011

R语言reshape2包处理数据2021.3.6,第1张

merge函数通过by选择合并某列的相同值。

这个包处理数据与excel包中的透视表有些类似

reshape包包含融合(melt)和重铸(cast),melt函数是将宽数据变为长数据,而cast则是将长数据变为宽数据。

melt函数就是将很宽的表融合成一列,变成很长的表,之后设定id.var=month和day就是固定搜索宽表中带有月日的列。这里我们使用airquality内置数据集作为示例。

因为初始数据集有六列数据。

但是melt函数只将前四列进行了数据融合,我这里猜测是无论什么数据集,他默认会将后两列作为ID,并且我们不用id.vars指明就不会显示。所以我们需要指明melt函数前四列作为变量值,后两列month和day作为ID。

图3和图1可以对照参考

cast函数分为dcast函数和acast函数,dcast函数用于重铸数据框,而acast函数用于重铸向量,矩阵或者数组。

指定重铸格式

这里按月份指定重铸,不知道应该对每月的数据进行何种处理则会报错。所以我们通过fun.aggregate参数指定计算函数,na.rm=T则用来计算时去除缺失值

在数据分析过程中,利用各种图表进行数据探索是必要的前期工作。描述性统计中就包括了直方图、散点图等工具来探索连续数据,对于分类数据,则可以采用条形图、交叉分组表等工具。Excel中所谓的“数据透视表”,其实就是一个交互式的交叉分组表。在R语言中可以很容易的用table()等函数得到相应的结果。对于一些更为复杂的任务,就需要其它的函数或包来完成。本例先以iris数据集为研究对象示范一些基本函数的用法,再介绍reshape包的强大功能。

iris数据集中有五个变量,其中Species表示鸢尾属花的子类,其它四个变量分别是花瓣和萼片的长度和宽度。你可以用head(iris)来观察原始数据的一些样本。我们的第一个任务是想计算不同种类花在四个指标上的平均值。用到的函数有tapply,by及aggregate。这篇文章对它们有所涉及。

将数据解包后,先用tapply函数尝试,但会发现该函数一次只允许输入一个变量。如果要完全四个变量的计算可能得用到循环。放弃这个函数来试试用by函数,该函数可以一次输入多个变量,但输出结果为一个list格式,还需要用do.call函数进行整合,有点麻烦。最方便友好的还是aggregate函数,直接输出为数据框格式。另外它还允许用公式来设置分组因子。

attach(iris)

names(iris)

tapply(X=Sepal.Length,INDEX=Species,FUN=mean)

temp <-by(data=iris[,1:4],INDICES=Species,FUN=mean)

do.call(rbind,temp)

aggregate(x=iris[,1:4],by=list(Species),FUN=mean)

aggregate(.~ Species, data = iris, mean)aggreagate函数表现已然不错,但还不够强大。比如说它没法直接得出表格的边际值,所以下面就请出本场的主角,即reshape包中的两员大将:melt与cast。这两个通常是配合使用,melt专门负责“融合”原始数据,形成长型(long)数据结构。cast则专职将融合后的数据“重铸”为新的形式(让人想起了“铁索连环”)。基本上只要有这两个函数,就能统一解决所有的汇总问题。

还是以上面的问题为例子,先加载reshape包,然后用melt函数进行融合数据,其中参数id指定了用Species为编号变量,measure参数用来指定分析变量(即被融合的变量),本例中只指定了参数id,所以原始数据中未包括在id中的其它变量均指定为分析变量。你可以观察到新的数据iris.melt其实就是堆叠(stack)后的数据。然后我们再用cast来重铸,cast函数中可以使用公式,波浪号左侧变量将纵列显示,右侧变量将以横行显示。margins参数设定了以列作为边际汇总方向。如果希望在计算中只包括两种花,可以使用subset参数。

library(reshape)

iris.melt <- melt(iris,id='Species')

cast(Species~variable,data=iris.melt,mean,margins="grand_row")

cast(Species~variable,data=iris.melt,mean,

subset=Species %in% c('setosa','versicolor'),

margins='grand_row')reshape包的作者也是ggplot2包的开发者,这个牛人是个完美主义者,在reshape包推出五年后,他重构代码推出了新的reshape2包。这个新包的特性在于:

改进算法,使计算与内存使用效能增强;

用dcast和acast代替了原来的cast函数;

用变量名来设定边际参数;

删除cast中的一些特性,因为他确认plyr包能更好的处理;

所有的melt函数族都增加了处理缺失值的参数。

下面我们以diamonds数据为例,来完成一个略为复杂的任务。我们希望计算不同切工和不同纯净度条件下,钻石的单位平均价格,并加以比较。首先加载reshape2包和ggplot2包,然后取子集。将原始数据融合,以切工、颜色和净度为编号变量。再利用dcast函数重铸数据,得到汇总结果。计算出单位价格,最后用条形图表现结果。

library(reshape2)

library(ggplot2)

data <- diamonds[1:7]

data.melt <- melt(data,id=c('cut','color','clarity'))

diam.sum <- dcast(data.melt,cut+clarity~variable,

subset=.(variable %in% c('price','carat')),mean)

diam.sum$average <- diam.sum$price/diam.sum$carat

p <- ggplot(diam.sum,aes(cut,average,fill=clarity))

p + geom_bar(position='dodge')

除了reshape包以外,R语言中还有stack、unstack、reshape等函数能完成类似的工作,但论功能的强大,还是首推reshape包中的哼哈二将。

宽数据是指数据集对所有的变量进行了明确的细分,各变量的值不存在重复循环的情况也无法归类。数据总体的表现为 变量多而观察值少。每一列为一个变量,每一行为变量所对应的值。例如s1-s10为变量名:

长数据是指数据集中的变量没有做明确的细分,即变量中至少有一个变量中的元素存在值严重重复循环的情况(可以归为几类),表格整体的形状为长方形,即 变量少而观察值多。一列包含了所有的变量,而另一列则是与之相关的值。例如S包含了所有的变量名:

长数据与宽数据之间的转换通常是作图需要,宽数据格式无法利用ggplot做出图形。例如分组柱状图等均需要长数据。此外,当数据清洗完成后,导入某些软件时,例如导入SPSS软件进行方差分析或者相关性分析等时候,宽数据格式会更好。因此需要对数据进行长宽格式相互转换。

目前常用的转换方式有两种,分别是手动复制粘贴和软件辅助(本文仅涉及R语言:R语言主要有tidyr包和reshape2包)。如数据量小的话,手动复制粘贴也是可以的;但当数据量十分庞大时,利用软件转换还是比较方便的。本文介绍R语言的tidyr包和reshape2包,掌握好这两个包的转换方法,数据前处理将会轻松很多。

可以通过R语言判断两种方法转化后的数据是否完全一致

可以用R语言判断两种方法转化后的数据是否完全一致,返回TRUE则为完全相等

由于data_wide_s的s1-s10并非按照数字顺序排列,因此有FALSE,但实际上是没有问题的

通过这里也可以看到,两种方法转换的数据观测值数和变量数一致,说明没有问题。

[1] https://blog.csdn.net/Ray_zhu/article/details/78679913

[2] https://cran.r-project.org/web/packages/tidyr/index.html

[3] https://cran.r-project.org/web/packages/reshape2/index.html