R语言reshape2包-官方文档学习
简介
reshape2包是由Hadley Wickham开发的用于数据重构的包,其主要功能函数为melt、cast,实现了长数据和宽数据之间的转换,包中还包含其它函数和数据集
使用得当,reshape2包是数据处理的利器
核心函数
长数据与宽数据
在学习如何使用核心函数melt和cast之前,我们先来了解下什么是长数据和宽数据
一般我们收集到的数据集会呈现为宽数据格式,这里以R自带的数据集airquality为例,介绍长数据和宽数据
宽数据:
> head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
宽数据是我们常见的数据集格式,因为这种格式符合数据收集的习惯和标准,数据集的每一列为一个观测变量,每一行为一组所有观测变量的观测值
个人理解:宽数据格式看重的是一次观测的各个变量相对应的观测值,所以各个变量是重点,而变量数目一般会比观测数多,这样就显得数据集较宽,故称为宽数据
长数据:
> data1 <- melt(airquality)
No id variables; using all as measure variables
> head(data1)
variable value
1 Ozone 41
2 Ozone 36
3 Ozone 12
4 Ozone 18
5 Ozone NA
6 Ozone 28
以上是运用melt函数得到的长数据,melt用法在下文详述,让我们先来观察下长数据的形式
长数据有两个特殊的列:variable和value,variable列用于存放观测变量,value列用于存放观测变量对应的观测值
个人理解:长数据格式用其特有的variable列和value列将观测结果细分,这在我们对单个变量进行分析而不是对所有变量进行分析时会简便得多,因其将每一个观测变量的观测值分开存储,造成variable列和value列较长,以致整个数据集显得较长,故称为长数据
melt函数
Convert an object into a molten data frame.
返回一个数据框
对不同的数据对象,melt函数有不同的使用方法:
- 针对数组的melt.array
- 针对数据框的melt.data.frame
- 针对向量的melt.default
- 针对列表的melt.list**
个人理解:melt意为“融化”,将宽数据转化为长数据,宽数据是一次观测记录了所有观测变量的观测值,melt的作用就是根据观测变量“融化”这些观测值,将观测值分开
melt.array
Melt an array.
其实可以处理的对象包括array、table和matrix
用法:
melt(data, varnames = names(dimnames(data)), …, na.rm = FALSE, as.is = FALSE, value.name = “value”)
参数:
- varnames:用于指定“融化”后形成的数据框的变量名
- na.rm:默认为FALSE,用于移除缺失值
- as.is:默认为FALSE,为FALSE时,函数会调用type.convert方法将维度名称转化,为TRUE时,维度名称仍会作为字符串类型
示例:
> a <- array(c(1:23, NA), c(2,3,4))
> melt(a, varnames = c('X', 'Y', 'Z'))
X Y Z value
1 1 1 1 1
2 2 1 1 2
3 1 2 1 3
4 2 2 1 4
5 1 3 1 5
6 2 3 1 6
7 1 1 2 7
8 2 1 2 8
9 1 2 2 9
10 2 2 2 10
11 1 3 2 11
12 2 3 2 12
13 1 1 3 13
14 2 1 3 14
15 1 2 3 15
16 2 2 3 16
17 1 3 3 17
18 2 3 3 18
19 1 1 4 19
20 2 1 4 20
21 1 2 4 21
22 2 2 4 22
23 1 3 4 23
24 2 3 4 NA
melt.data.frame
Melt a data frame into form suitable for easy casting.
我们主要使用的melt方法即这种处理数据框的方法
用法:
melt(data, id.vars, measure.vars, variable.name = “variable”, …, na.rm = FALSE, value.name = “value”, factorsAsStrings = TRUE)
参数:
- id.vars:用于指定标识变量,根据标识标量对其它变量进行“融化”,标识变量本身不进行“融化”
- measure.vars:用于指定测量变量,对测量变量进行“融化”,其它变量不进行“融化”
- 若只指定了id.vars和measure.vars中的一项,则把指定之外的变量作为另一项
- 若两者都未指定,则把因子和字符串类型的变量作为id.vars,其余变量作为measure.vars
示例:
> data2 <- melt(airquality)
No id variables; using all as measure variables
> head(data2)
variable value
1 Ozone 41
2 Ozone 36
3 Ozone 12
4 Ozone 18
5 Ozone NA
6 Ozone 28
# 指定Month和Day为标识变量
> data3 <- melt(airquality, id.vars = c('Month', 'Day'))
> head(data3)
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
# 指定Species为测量变量
> data4 <- melt(iris, measure.vars = 'Species')
> head(data4)
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
4 4.6 3.1 1.5 0.2 Species setosa
5 5.0 3.6 1.4 0.2 Species setosa
6 5.4 3.9 1.7 0.4 Species setosa
melt.default
Melt a vector. For vectors, makes a column of a data frame
将向量转化为数据框,不常用
用法:
melt(data, …, na.rm = FALSE, value.name = “value”)
示例:
> melt(c('data', 'science', 'R'))
value
1 data
2 science
3 R
melt.list
Melt a list by recursively melting each component.
可递归地拆分列表中的元素
用法:
melt(data, …, level = 1)
参数:
- level:默认为1,用于设置标签
示例:
> b <- as.list(c('emmm', 'hi', NA))
> melt(b)
value L1
1 emmm 1
2 hi 2
3 <NA> 3
> melt(b, level = 999)
value L999
1 emmm 1
2 hi 2
3 <NA> 3
cast函数
Cast functions Cast a molten data frame into an array or data frame.
cast函数有两种形式:
- acast:返回向量/矩阵/数组
- dcast:返回数据框
对于数据处理,我们一般是更希望得到数据框,所以下面只讲解dcast的使用,acast的使用和dcast相同,不同的只有函数的返回类型
个人理解:cast意为“铸造”,将长数据转化为宽数据,作者起的函数名很形象,melt就好像把金属融化,cast则是把融化的金属铸造,两者是相对的
dcast
用法:
dcast(data, formula, fun.aggregate = NULL, …, margins = NULL, subset = NULL, fill = NULL, drop = TRUE, value.var = guess_value(data))
参数:
- formula:“铸造”公式,为函数的核心参数,函数根据公式进行“铸造”,公式形式为x_variable + x_2 ~ y_variable + y_2,左边为标识变量,右边为测量变量,类似于melt函数中的id.vars参数和measure.vars参数
- fun.aggregate:聚集函数,如mean、median、sum
- fill:用于填充缺失值的值
- drop:默认为TRUE,是否删除缺失的组合
示例:
# 构造一个“融化”之后的数据集data5
# 指定Month和Day为标识变量
> data5 <- melt(airquality, id.vars = c('Month', 'Day'))
> head(data5)
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
# 将data5“铸造”
# “铸造”时使用“融化”指定的相同的标识变量
> data6 <- dcast(data5, Month + Day ~ variable)
> head(data6)
Month Day Ozone Solar.R Wind Temp
1 5 1 41 190 7.4 67
2 5 2 36 118 8.0 72
3 5 3 12 149 12.6 74
4 5 4 18 313 11.5 62
5 5 5 NA NA 14.3 56
6 5 6 28 NA 14.9 66
# 将“铸造”后的数据集与原始数据集对比,可以发现是相同的
> head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
其它函数
recast
Recast: melt and cast in a single step
一步操作进行melt和dcast
用法:
recast(data, formula, …, id.var, measure.var)
示例:
> head(french_fries)
time treatment subject rep potato buttery grassy rancid painty
61 1 1 3 1 2.9 0.0 0.0 0.0 5.5
25 1 1 3 2 14.0 0.0 0.0 1.1 0.0
62 1 1 10 1 11.0 6.4 0.0 0.0 0.0
26 1 1 10 2 9.9 5.9 2.9 2.2 0.0
63 1 1 15 1 1.2 0.1 0.0 1.1 5.1
27 1 1 15 2 8.8 3.0 3.6 1.5 2.3
> data7 <- recast(french_fries, time ~ variable, id.var = 1:4)
Aggregation function missing: defaulting to length
> head(data7)
time potato buttery grassy rancid painty
1 1 72 72 72 72 72
2 2 72 72 72 72 72
3 3 72 72 72 72 72
4 4 72 72 72 72 72
5 5 72 72 72 72 72
6 6 72 72 72 72 72
melt_check
Check that input variables to melt are appropriate.
检查数据集是否适合“融化”,返回标识变量和测量变量
用法:
melt_check(data, id.vars, measure.vars, variable.name, value.name)
参数:
- id.vars:用于指定标识变量
- measure.vars:用于指定测量变量
- 若只指定了id.vars和measure.vars中的一项,则把指定之外的变量作为另一项
- 若两者都未指定,则把离散变量作为id.vars,其余变量作为measure.vars
示例:
> reshape2:::melt_check(airquality, variable.name = 'variable', value.name = 'value')
No id variables; using all as measure variables
$id
character(0)
$measure
[1] "Ozone" "Solar.R" "Wind" "Temp" "Month" "Day"
> reshape2:::melt_check(airquality, id.vars = c('Month', 'Day'), variable.name = 'variable', value.name = 'value')
$id
[1] "Month" "Day"
$measure
[1] "Ozone" "Solar.R" "Wind" "Temp"
parse_formula
Parse casting formulae.
“铸造”公式有两种写法,一种是字符串写法,另一种是引用变量写法,parse_formula的作用就是将字符串写法转换为引用变量写法,但实际使用中字符串写法更简单易读,故该函数使用不多,不作详述,感兴趣可查看官方文档
colsplit
Split a vector into multiple columns
根据规则将向量中的每一个元素划分为多项组成数据框,并智能确定每一列的数据类型,处理数据框变量名时很有用
用法:
colsplit(string, pattern, names)
参数:
- string:待划分的字符串向量或因子
- pattern:划分规则的正则表达式
- names:指定换分后的列名
示例:
> x <- c("a_1", "a_2", "b_2", "c_3")
> vars <- colsplit(x, "_", c("trt", "time"))
> vars
trt time
1 a 1
2 a 2
3 b 2
4 c 3
# 划分后字符型的数字被自动调整为数值型
> str(vars)
'data.frame': 4 obs. of 2 variables:
$ trt : chr "a" "a" "b" "c"
$ time: int 1 2 2 3
add_margins
Add margins to a data frame.
去掉数据框的行名并把边界变量(margining variables)转化为因子
个人理解:该函数的实际作用价值未知
用法:
add_margins(df, vars, margins = TRUE)
参数:
- vars:指定边界向量
示例:
> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
> data8 <- add_margins(mtcars, vars = 'cyl')
> head(data8)
mpg cyl disp hp drat wt qsec vs am gear carb
1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
# 可以看到行名已经被去除
> str(mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
> str(data8)
'data.frame': 64 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : Factor w/ 4 levels "4","6","8","(all)": 2 2 1 2 3 2 3 1 1 2 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
# 可以看到变量cyl的数据类型已由数值型变为因子
自带数据集
french_fries
Sensory data from a french fries experiment.
实验数据:使用三种不同的油对薯条口感的影响
> str(french_fries)
'data.frame': 696 obs. of 9 variables:
$ time : Factor w/ 10 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
$ treatment: Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
$ subject : Factor w/ 12 levels "3","10","15",..: 1 1 2 2 3 3 4 4 5 5 ...
$ rep : num 1 2 1 2 1 2 1 2 1 2 ...
$ potato : num 2.9 14 11 9.9 1.2 8.8 9 8.2 7 13 ...
$ buttery : num 0 0 6.4 5.9 0.1 3 2.6 4.4 3.2 0 ...
$ grassy : num 0 0 0 2.9 0 3.6 0.4 0.3 0 3.1 ...
$ rancid : num 0 1.1 0 2.2 1.1 1.5 0.1 1.4 4.9 4.3 ...
$ painty : num 5.5 0 0 0 5.1 2.3 0.2 4 3.2 10.3 ...
smiths
Demo data describing the Smiths.
描述John Smith和Mary Smith的小样本数据
> smiths
subject time age weight height
1 John Smith 1 33 90 1.87
2 Mary Smith 1 NA NA 1.54
> str(smiths)
'data.frame': 2 obs. of 5 variables:
$ subject: Factor w/ 2 levels "John Smith","Mary Smith": 1 2
$ time : int 1 1
$ age : num 33 NA
$ weight : num 90 NA
$ height : num 1.87 1.54
tips
Tipping data
关于小费的记录数据
> str(tips)
'data.frame': 244 obs. of 7 variables:
$ total_bill: num 17 10.3 21 23.7 24.6 ...
$ tip : num 1.01 1.66 3.5 3.31 3.61 4.71 2 3.12 1.96 3.23 ...
$ sex : Factor w/ 2 levels "Female","Male": 1 2 2 2 1 2 2 2 2 2 ...
$ smoker : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
$ day : Factor w/ 4 levels "Fri","Sat","Sun",..: 3 3 3 3 3 3 3 3 3 3 ...
$ time : Factor w/ 2 levels "Dinner","Lunch": 1 1 1 1 1 1 1 1 1 1 ...
$ size : int 2 3 3 2 4 4 2 4 2 2 ...