R语言专题:数据重塑
R 语言中的数据重塑是关于改变数据被组织成行和列的方式。
R 语言中的数据处理通常是通过将输入数据作为数据框来完成的。
R语言的数据框的行和列中提取数据比较容易,但是在某些情况下,我们需要的数据框格式与我们接收数据框的格式不同。
R 语言提供了拆分数据框,合并数据框以及行列互换的功能。
melt()函数
reshape/reshape2 的 melt 函数是个 S3 通用函数,它会根据数据类型(数据框,数组或列表)选择 melt.data.frame, melt.array 或 melt.list 函数进行实际操作。
- 如果是数组(array)类型,melt 的用法就很简单,它依次对各维度的名称进行组合,将数据进行线性/向量化。如果数组有 n 维,那么得到的结果共有 n+1 列,前 n 列记录数组的 位置信息,最后一列才是观测值。
> datax<-array(1:8,dim=c(2,2,2))
> datax
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
> library(reshape2)
> x<-melt(datax)
> x
X1 X2 X3 value
1 1 1 1 1
2 2 1 1 2
3 1 2 1 3
4 2 2 1 4
5 1 1 2 5
6 2 1 2 6
7 1 2 2 7
8 2 2 2 8
> y<-melt(datax,varnames = LETTERS[24:26],value.name = "scores")
> y
X Y Z scores
1 1 1 1 1
2 2 1 1 2
3 1 2 1 3
4 2 2 1 4
5 1 1 2 5
6 2 1 2 6
7 1 2 2 7
8 2 2 2 8
注意,若使用reshape包,value.name无法设置成功
## S3 method for class 'array'
melt(
data,
varnames = names(dimnames(data)),
...,
na.rm = FALSE,
as.is = FALSE,
value.name = "value"
)
R语言数据变形melt用法
melt(data,
id.vars,
measure.vars,
variable_name = "variable", na.rm = !preserve.na, preserve.na = TRUE, ...)
属性 | 说明 |
---|---|
data | Data set to melt |
id.vars | Id variables. If blank, will use all non measure.vars variables. Can be integer (variable position) or string (variable name) |
measure.vars | Measured variables. If blank, will use all non id.vars variables. Can be integer (variable position) or string (variable name) |
variable_name | Name of the variable that will store the names of the original variables |
需要确定哪些变量是id变量( id variables),哪些是测量变量(measured variables)。
如果只提供其中一个(id.var或measure.vars), melt将假定数据集中的未指定的其余变量属于另一个变量(即若只指定了id.var的对象,其余变量属于measure.vars)。
如果不提供,melt将假设因子和字符变量是id variables,并且所有其他的是measured variables。
其实变换前提就是指定哪些数据是id variables,哪些是measured variables
简化版:
- id.vars:你不想改变的数据列
- measure.vars:你要melt的数据
- variable.name:melt操作后,为新列变量取名
- value.name:新列对应值的变量名
> d<-data.frame(area=c(1,1,2,3,3,1),PH=c(2.3,2.9,4.0,7.9,8.0,3.2),temp=c(23,21,19,10,13,19),p=c(0.99,0.95,0.85,0.34,0.25,0.90))
> d
area PH temp p
1 1 2.3 23 0.99
2 1 2.9 21 0.95
3 2 4.0 19 0.85
4 3 7.9 10 0.34
5 3 8.0 13 0.25
6 1 3.2 19 0.90
> melt(d,id.vars = "area")
area variable value
1 1 PH 2.30
2 1 PH 2.90
3 2 PH 4.00
4 3 PH 7.90
5 3 PH 8.00
6 1 PH 3.20
7 1 temp 23.00
8 1 temp 21.00
9 2 temp 19.00
10 3 temp 10.00
11 3 temp 13.00
12 1 temp 19.00
13 1 p 0.99
14 1 p 0.95
15 2 p 0.85
16 3 p 0.34
17 3 p 0.25
18 1 p 0.90
> melt(d,id.vars = c("area","PH"))
area PH variable value
1 1 2.3 temp 23.00
2 1 2.9 temp 21.00
3 2 4.0 temp 19.00
4 3 7.9 temp 10.00
5 3 8.0 temp 13.00
6 1 3.2 temp 19.00
7 1 2.3 p 0.99
8 1 2.9 p 0.95
9 2 4.0 p 0.85
10 3 7.9 p 0.34
11 3 8.0 p 0.25
12 1 3.2 p 0.90
度量变量有两个,每一个度量变量都有6个值,所以,共有12条观测,value的值是度量变量的值
> melt(d,measure.vars = "area")
PH temp p variable value
1 2.3 23 0.99 area 1
2 2.9 21 0.95 area 1
3 4.0 19 0.85 area 2
4 7.9 10 0.34 area 3
5 8.0 13 0.25 area 3
6 3.2 19 0.90 area 1
#此时area为度量变量,value列将显示其变量值
1、需要安装的包
install.packages("reshape2")
install.packages("knitr")
2 创建数据集
data<-data.frame(Name = c("苹果","谷歌","脸书","亚马逊","腾讯"),
Company = c("Apple","Google","Facebook","Amozon","Tencent"),
Sale2013 = c(5000,3500,2300,2100,3100),
Sale2014 = c(5050,3800,2900,2500,3300),
Sale2015 = c(5050,4000,3200,2800,3700),
Sale2016 = c(6000,4800,4500,3500,4300))
3、原始数据展示
> data
Name Company Sale2013 Sale2014 Sale2015 Sale2016
1 苹果 Apple 5000 5050 5050 6000
2 谷歌 Google 3500 3800 4000 4800
3 脸书 Facebook 2300 2900 3200 4500
4 亚马逊 Amozon 2100 2500 2800 3500
5 腾讯 Tencent 3100 3300 3700 4300
4、melt数据变形
mydata<-melt(data,id.vars=c("Name","Company"),variable.name="Year",value.name="Sale")
5、数据变形之后的数据展示
> mydata<-melt(data,id.vars=c("Name","Company"),variable.name="Year",value.name="Sale")
> mydata
Name Company Year Sale
1 苹果 Apple Sale2013 5000
2 谷歌 Google Sale2013 3500
3 脸书 Facebook Sale2013 2300
4 亚马逊 Amozon Sale2013 2100
5 腾讯 Tencent Sale2013 3100
6 苹果 Apple Sale2014 5050
7 谷歌 Google Sale2014 3800
8 脸书 Facebook Sale2014 2900
9 亚马逊 Amozon Sale2014 2500
10 腾讯 Tencent Sale2014 3300
11 苹果 Apple Sale2015 5050
12 谷歌 Google Sale2015 4000
13 脸书 Facebook Sale2015 3200
14 亚马逊 Amozon Sale2015 2800
15 腾讯 Tencent Sale2015 3700
16 苹果 Apple Sale2016 6000
17 谷歌 Google Sale2016 4800
18 脸书 Facebook Sale2016 4500
19 亚马逊 Amozon Sale2016 3500
20 腾讯 Tencent Sale2016 4300
长宽数据转换
什么是长数据?
长数据一般是指数据集中的变量没有做明确的细分,即变量中至少有一个变量中的元素存在值严重重复循环的情况(可以归为几类),表格整体的形状为长方形,即变量少而观察值多。
什么是宽数据?
宽数据是指数据集对所有的变量进行了明确的细分,各变量的值不存在重复循环的情况也无法归类。数据总体的表现为 变量多而观察值少。
3.为什么需要转换?
长数据与宽数据之间的转换通常为以下两个原因:
- 时间序列数据想要观察多个种类的变量在一段时间内的变化,如上例,宽数据格式无法利用ggplot做出图形。
- 当数据清洗完成后,导入某些软件时,例如导入SPSS软件时宽数据格式会更好。
宽数据变为长数据
将宽数据变为长数据 melt函数
data2<-melt(data1,id.vars="area",variable.name = "year",value.name = "GDP")
长数据变为宽数据
library(tidyr)
data3<-spread(data2,year,GDP)
Year是类别变量,有几类,就会转化为几列
spread {tidyr}
spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE, sep = NULL)
参数说明:
参数 | 说明 |
---|---|
Key | 用于转化为新数据列的目标列列名 |
Value | 作为新数据列数据值的目标列列名 |
总结:
宽数据是我们常见的数据集格式,因为这种格式符合数据收集的习惯和标准,数据集的每一列为一个观测变量,每一行为一组所有观测变量的观测值。
宽数据格式看重的是一次观测的各个变量相对应的观测值,所以各个变量是重点,而变量数目一般会比观测数多,这样就显得数据集较宽,故称为宽数据。
为数据框增加新变量
向数据框中添加新的列,以数据集Loblolly为例
height | age | Seed | |
---|---|---|---|
1 | 4.51 | 3 | 301 |
15 | 10.89 | 5 | 301 |
29 | 28.72 | 10 | 301 |
43 | 41.74 | 15 | 301 |
57 | 52.70 | 20 | 301 |
71 | 60.92 | 25 | 301 |
2 | 4.55 | 3 | 303 |
16 | 10.92 | 5 | 303 |
数据说明:
The Loblolly data frame has 84 rows and 3 columns of records of the growth of Loblolly pine trees.
height a numeric vector of tree heights (ft). 火炬松
age a numeric vector of tree ages (yr).
Seed an ordered factor indicating the seed source for the tree. The ordering is according to increasing maximum height.
将R自带数据集的前6条记录截取出来赋值给data,以免误操作
> data<-head(Loblolly)
> data
height age Seed
1 4.51 3 301
15 10.89 5 301
29 28.72 10 301
43 41.74 15 301
57 52.70 20 301
71 60.92 25 301
使用一个$符
> data$logheight<-log(data$height)
> data
height age Seed logheight
1 4.51 3 301 1.506297
15 10.89 5 301 2.387845
29 28.72 10 301 3.357594
43 41.74 15 301 3.731460
57 52.70 20 301 3.964615
71 60.92 25 301 4.109562
within函数
必须在新添加的变量中加上花括号
> data2<-head(Loblolly)
> data2<-head(Loblolly)
> data2
height age Seed
1 4.51 3 301
15 10.89 5 301
29 28.72 10 301
43 41.74 15 301
57 52.70 20 301
71 60.92 25 301
使用transform函数
> data3<-head(Loblolly)
> data3<-transform(data3,logheight=log(height),powerage=age^2)
> data3
height age Seed logheight powerage
1 4.51 3 301 1.506297 9
15 10.89 5 301 2.387845 25
29 28.72 10 301 3.357594 100
43 41.74 15 301 3.731460 225
57 52.70 20 301 3.964615 400
71 60.92 25 301 4.109562 625
删除数据框中的某一列
使用subset()函数
> data4<-subset(data3,select=-c(logheight,powerage))
> data4
height age Seed
1 4.51 3 301
15 10.89 5 301
29 28.72 10 301
43 41.74 15 301
57 52.70 20 301
71 60.92 25 301
也可以使用负号
> data4<-data3[,-c(4,5)]
> data4
height age Seed
1 4.51 3 301
15 10.89 5 301
29 28.72 10 301
43 41.74 15 301
57 52.70 20 301
71 60.92 25 301
> data4<-data3[-4]
> data4
height age Seed powerage
1 4.51 3 301 9
15 10.89 5 301 25
29 28.72 10 301 100
43 41.74 15 301 225
57 52.70 20 301 400
71 60.92 25 301 625
数据框的合并
除了之前介绍了rbind,cbind, merge,这里介绍plyr包中的join函数。
语法:
join(x, y, by = NULL, type = "left", match = "all")
说明:
其中x和y是要被合并的数据框;
by为x和y中的连接字段;
type为合并类型,有左连、右连、内连和全连四种;
match用来数据合并过程中重复值的处理,默认情况下不排除重复值,当指定first时,则保留重复值中的第一个。
需要的包:
> library(plyr)
> library(reshape)
Plyr:数据包的功能 Tools for Splitting, Applying and Combining Data
对数据进行拆分,应用,组合介绍aaply adply alply 对数组 数据框 列表进行拆分后应用函数
join进行数据框的合并
1 分别创建df1和df2数据框并显示
> df1<-data.frame(x=c('a','b','c','d','d'),y=1:5)
> df2<-data.frame(x=c('a','b','d','e'),z=6:9)
> df1;df2
x y
1 a 1
2 b 2
3 c 3
4 d 4
5 d 5
x z
1 a 6
2 b 7
3 d 8
4 e 9
2 以x为连接项对数据框进行左连接
> df3<-join(df1,df2,by="x",type="left")
> df3
x y z
1 a 1 6
2 b 2 7
3 c 3 NA
4 d 4 8
5 d 5 8
3 以x为连接项对数据框进行右连接
> df3<-join(df1,df2,by="x",type='right')
> df3
x y z
1 a 1 6
2 b 2 7
3 d 4 8
4 d 5 8
5 e NA 9
join函数-内连接和全连接
内连接相当于是两个数据框关于键值x的交集,全连接相当于两个数据框关于键值x的并集
> df4<-join(df1,df2,by="x",type='inner')
> df4
x y z
1 a 1 6
2 b 2 7
3 d 4 8
4 d 5 8
> df5<-join(df1,df2,by="x",type='full')
> df5
x y z
1 a 1 6
2 b 2 7
3 c 3 NA
4 d 4 8
5 d 5 8
6 e NA 9