【R语言学习笔记】实现类似数据透视表的若干方式

EXCEL中的很强大的功能就是数据透视表,不得不说,透视表解决了很多数据汇总的问题,包括可以计数、求和、均值等一系列操作;然而数据透视表比较慢,而且对于后续的处理不是很友好。既然用R来分析数据,则不能把所有数据放在excel里然后用R分析,通过R in action的启发,加上很多自己的实验,总结三种透视表的方法。

【一】SQL语言的透视表

一般在数据分析处理前,从数据库中提取会有若干字段的csv,我们可以利用R进行二次加工,看一个例子:

首先建立一个data.frame-test

Region Surname Age height salary

1 辽宁 王 25 180 100

2 北京 杨 27 185 50

3 山东 王 27 185 80

4 辽宁 齐 27 190 55

我们首先要统计一下,各省市的平均年龄是多少?这个时候的逻辑其实是按照区域汇总,然后求均值

首先用sql包

library(sqldf)

然后用SQL语言进行选择求值,需要注意的是,SQL中的均值和R不同,R中是mean函数,SQL是avg。

用如下语句,其实就是选择Region这一列,对Age求平均值,最后以Region分组

sqldf('select Region, avg(Age) from test group by Region')

结果如下:

Region avg(Age)

1 北京 27

2 山东 27

3 辽宁 26

同理,如果我要统计各姓氏的工资总和,

sqldf('select Region, avg(Age) from test group by Region')

Surname sum(salary)

1 杨 50

2 王 180

3 齐 55

顺便我要按照工资高低排序

sqldf('select Surname, sum(salary) from test group by surname order by salary desc')

order by 是排序,desc是排倒序,结果为

Surname sum(salary)

1 王 180

2 齐 55

3 杨 50

其实这就是初步的实现了数据透视表的功能,但是这个格式还是字段型的格式,也就是一行是一个字段的列表,如果想分类汇总,可能在excel中还需要sumif,sumifs,sumproduct等函数做出美观的效果。如果想直接按照行列式的数据透视表,就需要下面的方法。

【二】reshape包的透视表

reshape包的透视表可以做出和excel一模一样的功能,但是首先需要数据标准化,也就是melt,这部分的数据标准化其实就是标准化成字段模式,举个例子:

这个表f

        王 齐 杨

salary 180 55 50

标准化之后就成了之前的表e:

Surname sum(salary)

1 王 180

2 齐 55

3 杨 50

具体的过程可以用如下代码

library(reshape2)
melt(f,varnames = c('field','Surname'))

第一个是调用reshape2包,因为reshape包竟然无法使用varnames和value.names函数,也不知道为什么;然后处理一下数据集,让他看起来和表e一样

field Surname value

1 salary 王 180

2 salary 齐 55

3 salary 杨 50

下面说说区别,看到表e有三列,而之前的表e的第一列可以认为是列序号,这就是一个微小的差异,也就是针对melt后的表,一定要有一个字段的,而字段不在表头,在行上,基于这个推论,也就是说

melt后的标准化数据一定至少有三列

即使一列是没什么用的。

melt后就可以开始cast了,这里面不用这个例子,用最原始的表test

之前说过,test已经是标准化之后的数据了,我们现在想取region和surname下的salary水平,利用如下代码

library(reshape)

cast(test,Region~Surname,value='salary')

结果如下:

Region 齐 王 杨

1 北京 NA NA 50

2 辽宁 55 100 NA

3 山东 NA 80 NA

或者看身高的均值g

cast(test,Region~Age,value='height',mean,na.rm=T)

Region 25 27

1 北京 NaN 185

2 辽宁 180 190

3 山东 NaN 185

可以看到有很多NA和NAN的值,因为我们的原始数据不是在每个交叉表里都有,所以会有NAN值

可以利用

na.omit(g)

删除含有缺失值的一行

剩下:

Region 25 27

2 辽宁 180 190

或者为了分析方便,如后续的分析应用到mean,sum等加上na.rm=T

再或者为了表示NA值就是0,可以赋值

g[is.na(g)]<-0

Region 25 27

1 北京 0 185

2 辽宁 180 190

3 山东 0 185

除此之外,还有subset函数以及其他的针对数据异常数据的提取和改名,可以保证随心所欲的处理R的数据源。

【三】aggregate函数

还是原来的test数据框

Region Surname Age height salary

1 辽宁 王 25 180 100

2 北京 杨 27 185 50

3 山东 王 27 185 80

4 辽宁 齐 27 190 55

这时候,如果我想要对姓氏的年龄做平均,利用

h<-aggregate(test$Age*,by=list(test$Surname),mean)

得到

h

Group.1 x

1 齐 27

2 王 26

3 杨 27

或者直接改掉Group.1的名字

h<-aggregate(test$Age,by=list(Surname=Surname),mean)

得到

h

Surname x

1 齐 27

2 王 26

3 杨 27

同理,我要是想要算区域的总工资

j<-aggregate(test$salary,by=list(Region=Region),sum)

j

Region x

1 北京 50

2 辽宁 155

3 山东 80

同时,aggregate函数还可以对多列进行汇总,比如对身高和工资的汇总

j<-aggregate(test$salary,by=list(Age=Age,height=height),sum)

这里是对test里的salary一列汇总,同时条件是筛选出age和height相同的进行加总,结果为

j

Age height x

1 25 180 100

2 27 185 130

3 27 190 55

THE END

你可能感兴趣的:(R)