欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[R数据预处理] 数据重塑

程序员文章站 2024-02-28 19:34:04
...

统计中待分析的数据框通常有两种形式:
(1)长型数据(堆叠数据),长型数据是各变量取值在一列中,而对应的变量名在另一列。
(2)宽型数据(非堆叠数据),宽型数据一般是各变量取值类型一致,而变量以不同列的形式构成。(常用)

1. 例如iris的前四列子集即是一个典型的宽型数据。例如下面将宽型数据转为长型数据:

data_w <- iris[,1:4]
data_l <- stack(data_w)
head(data_l)
  values          ind
1    5.1 Sepal.Length
2    4.9 Sepal.Length
3    4.7 Sepal.Length
4    4.6 Sepal.Length
5    5.0 Sepal.Length
6    5.4 Sepal.Length
data_w <- unstack(data_l)

只要在一列中存在分类变量,都可以将其看作是长型数据。
在上例中iris的前四列可以看作是宽型数据,但最后两列可以看作是一个长型数据。

2. 可以根据Species变量将数据转为宽型。并得到各花种类的平均值。

> subdata<-iris[,4:5]
> head(subdata)                        #长型数据
  Petal.Width Species
1         0.2  setosa
2         0.2  setosa
3         0.2  setosa
4         0.2  setosa
5         0.2  setosa
6         0.4  setosa
> data_w<-unstack(subdata)
> head(data_w)
  setosa versicolor virginica      #宽型数据
1    0.2        1.4       2.5
2    0.2        1.5       1.9
3    0.2        1.5       2.1
4    0.2        1.3       1.8
5    0.2        1.5       2.2
6    0.4        1.3       2.1

> colMeans(data_w)         #列平均值
    setosa versicolor  virginica 
     0.246      1.326      2.026 

数据重塑计算

3. 在上例中我们先转换数据格式再计算分析结果,而更常见的是一步直接得到分析结果。

library(reshape2)
dcast(data=subdata, # 分析对象
formula=Species~., # 数据分组的方式
value.var='Petal.Width', # 要计算的数值对象
fun=mean) # 计算用函数名

    Species     .
1     setosa 0.246
2 versicolor 1.326
3  virginica 2.026

dcast的思路和aggregate很相似,都是根据变量切分数据,再对分组后的数据进行计算,
但dcast的输出格式和功能在多维情况下要方便很多。

4. 将一个宽型数据融合成一个长型数据,即melt函数。例如我们将iris数据集进行融合。

iris_long <- melt(data=iris, # 要融合的对象
id='Species') # 哪些变量不参与到融合中

> head(iris_long)
  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

一个纯粹的长型数据,只包含一个数值变量,其它均为分类变量。
而一个纯粹的宽型数据,则不包含分类变量,均为数值变量。
而现实中的数据多半是二者的混杂,正如iris数据集那样。

5. 下面的例子就是将之前生成的数据进行汇总计算

dcast(data=iris_long,
formula=Species~variable,
value.var='value',fun=mean)

     Species Sepal.Length Sepal.Width
1     setosa        5.006       3.428
2 versicolor        5.936       2.770
3  virginica        6.588       2.974
  Petal.Length Petal.Width
1        1.462       0.246
2        4.260       1.326
3        5.552       2.026

dcast函数的使用前提
数据中已经存在分类变量,例如sex或者smoke
根据分类变量划分数据
再计算某个数值变量的指标

6. 小练习

tips数据集练习,它是一个餐厅侍者收集的关于小费的数据,其中包含了七个变量,
包括总费用、付小费的金额、付款者性别、是否吸烟、日期、日间、顾客人数。
计算不同性别顾客是否会支付不同的小费比例。则可以按sex变量汇集数据。
或者,按sex和size变量划分数据,分别计算小费金额。

dcast(tips,sex~.,value.var='tip',fun=mean)
dcast(tips,sex~size,value.var='tip',fun=mean)

7. 合并两个数据框

按id号将它们合为一个数据框。不能使用cbind来合并,因为id的顺序不一样。
使用merge函数,按照id来合并两组数据,这种操作思路和数据库操作中的join是类似的。

datax <- data.frame(id=c(1,2,3),gender=c(23,34,41))
datay <- data.frame(id=c(3,1,2),name=c('tom','john','ken'))
merge(datax,datay,by='id')

8. 数据按变量拆分

常规的数据分拆其实就是取子集,使用subset函数即可完成。
非常规一点的数据拆分是按照某个分类变量进行的。
例如需要对iris数据中按不同的花的属性来分拆数据,使用split函数。

iris_splited <- split(iris,f=iris$Species)
class(iris_splited)   #拆分后数据类型为列表list
[1] "list"
> head(iris_splited[[1]])

9. 数据按变量合并

split函数可以将一个数据框拆分成多个数据框,存在一个列表对象中。
合并这个列表,只需要使用unsplit函数即可。

unsplit(iris_splited,f=iris$Species)