https://zhuanlan.zhihu.com/p/22249895?refer=rdatamining
前言
reshape2是又一个用来做数据处理的拓展包,用于实现宽格式数据与长格式数据之间的互转。如果你熟悉结构化数据库查询,那么你一定知道列转行与行转列,宽长数据之间互转与之类似;如果你不熟悉的也没关系,它很简单,接着往下看你就能很快熟悉并掌握了。首先我们通过一个数据集来解释什么是长宽数据。
一、宽数据与长数据
1. 宽数据
定义:每一列为一个观测变量,每一行为变量对应的观测值。
# ozone wind temp
# 1 23.62 11.623 65.55
# 2 29.44 10.267 79.10
# 3 59.12 8.942 83.90
# 4 59.96 8.794 83.97
2. 长数据
定义:一列就包含了所有的变量,而另一行则是与之相关的值(长数据不一定只有两列)。
# variable value
# 1 ozone 23.615
# 2 ozone 29.444
# 3 wind 11.623
# 4 wind 10.267
# 5 temp 65.548
# 6 temp 79.100
二、reshape2包
在reshape2包中,我们用得比较多的是melt和cast两个函数。
- melt函数:对宽数据进行处理,得到长数据;
- cast函数:对长数据进行处理,得到宽数据。
1. melt()函数
调用公式:
> melt(data, id.vars, measure.vars, variable.name = "variable", ...,
na.rm = FALSE, value.name = "value", factorsAsStrings = TRUE)
data1 <- melt(iris)
head(iris)
Species variable value
1 setosa Sepal.Length 5.1
2 setosa Sepal.Length 4.9
3 setosa Sepal.Length 4.7
4 setosa Sepal.Length 4.6
5 setosa Sepal.Length 5.0
6 setosa Sepal.Length 5.4
(2)加入识别指标[id.vars = ],R会根据id.vars进行数据整理,即除去指标中指定的变量,其他数据都被进行了变形。此处使用R内置数据集'airquality'
数据转换目的:得到每个月(Month)以及每天(Day)的Ozone, Solar.R, Wind以及Temp的值。
data2 <- melt(airquality,id.vars = c("Month","Day"))
head(data2)
Month Day variable value
1 5 1 Ozone 41
2 5 2 Ozone 36
3 5 3 Ozone 12
4 5 4 Ozone 18
5 5 5 Ozone NA
6 5 6 Ozone 28
data6 <- melt(iris,measure.vars = "Species")
head(data6,3)
Sepal.Length Sepal.Width Petal.Length Petal.Width variable value
1 5.1 3.5 1.4 0.2 Species setosa
2 4.9 3.0 1.4 0.2 Species setosa
3 4.7 3.2 1.3 0.2 Species setosa
# 指定了'Species'列为观测对象,则变量名占一列,具体值占一列
2. cast()函数
cast()函数的运用并没有melt()直观,在reshape2中有好几个cast版本的函数:- 对于data.frame格式的数据,需要使用dcast()函数。
- 对于向量、矩阵或者数组格式的数据,需要使用acast()函数。
由于在平常的数据处理上,我们更多的使用格式为'dataframe'的数据,因此我们重点讲解dcast()函数的使用。
(1) dcast() 调用公式:dcast(data, formula, fun.aggregate = NULL)
dcast借助于公式来描述数据的形状,左边参数表示"ID variables",而右边的参数表示measured variables。可能需要几次尝试,才能找到合适的公式。此处使用上文已经过melt转换后的数据集'data2'
数据转换目的:在一行上展示所有Month和Day组合下的Ozone、Solar.R、Wind和Temp值
data3 <- dcast(data2,Month + Day ~ variable)
head(data3)
(2)上文中,我们指定Month和Day为'ID Variables',得到重铸后的数据集,但如果只指定Month一个变量,而由于Day变量的存在,新的数据集无法展现所有的数据(Day不唯一)R会报错,为此,我们需要聚合(aggregate)这些数据,包括mean()、median()、sum()等
data4 <- dcast(data2,Month ~ variable,fun.aggregate = mean,na.rm=TRUE)
# 分别得到各月各个特征的均值
> data4
Month Ozone Solar.R Wind Temp
1 5 23.61538 181.2963 11.622581 65.54839
2 6 29.44444 190.1667 10.266667 79.10000
3 7 59.11538 216.4839 8.941935 83.90323
4 8 59.96154 171.8571 8.793548 83.96774
5 9 31.44828 167.4333 10.180000 76.90000
(3)fun函数也可以自行编写(自编函数)
# 查看缺失值
find_null <- function(x){
return(sum(is.na(x)))}
data5 <- dcast(data2,Month~variable,find_null)
> data5
Month Ozone Solar.R Wind Temp
1 5 5 4 0 0
2 6 21 0 0 0
3 7 5 0 0 0
4 8 5 3 0 0
5 9 1 0 0 0
附学习文档:
- An Introduction to reshape2
- Data Manipulation with reshape2
- 探索R包reshape2:揉数据的最佳伴侣
- How to reshape data in R: tidyr vs reshape2
- Reshape and aggregate data with the R package reshape2
关于R语言请关注专栏:R语言与数据挖掘 - 知乎专栏
欲加入R语言交流群,请搜索公众号“如临春风”,回复“R语言”或“r语言”即可获取二维码信息。