2016年4月12日

数据整理

摘要:讲解R语言如何操作数据,能对数据进行自由的操作转换。

案例和练习:餐厅小费数据的分析

  • 数据变换
  • 数据重塑
  • 拆分合并
  • 汇总数据

数据变换

取数据子集

两种方式取数据子集:

  • 使用方括号加索引来取子集
  • subset函数

取iris中花种类为setosa的子集,并取后三列数据。

data_sub <- subset(iris, Species=='setosa',3:5)
data_sub <- with(iris,iris[Species=='setosa',3:5])

编码转换

对数据框中的值进行映射

iris_tr <- transform(iris, v1=log(Sepal.Length))

变量离散化

将变量根据数值大小分为四组,而且要求每组的样本数大体一样。

people = data.frame(age=c(13,42,55,64,30,53,24),
                    gender=c("M","F","F","M","M","F","M"))
groupvec = c(0,40,60,100)
labels <- c('青年','中年','老年')

people$label <- with(people,cut(people$age,breaks=groupvec,labels=labels))

people
##   age gender label
## 1  13      M  青年
## 2  42      F  中年
## 3  55      F  中年
## 4  64      M  老年
## 5  30      M  青年
## 6  53      F  中年
## 7  24      M  青年

数据类型转换

vec <- rep(c(0,1),c(4,6))
vec_fac <- factor(vec,labels=c('male','femal'))
levels(vec_fac) 
## [1] "male"  "femal"

因子合并

vec <- rep(c(0,1,3),c(4,6,2))
vec_fac <- factor(vec)
levels(vec_fac)  <- c('male','femal','male')

因子重设

vec <- rep(c('b','a'),c(4,6))
vec_fac <- factor(vec)
levels(vec_fac)
## [1] "a" "b"
relevel(vec_fac,ref='b')
##  [1] b b b b a a a a a a
## Levels: b a

数据重塑

数据的两种形状

统计中待分析的数据框通常有两种形式

  • 长型数据(堆叠数据),长型数据是各变量取值在一列中,而对应的变量名在另一列。
  • 宽型数据(非堆叠数据),宽型数据一般是各变量取值类型一致,而变量以不同列的形式构成。

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

data_w <- iris[,1:4]
data_l <- stack(data_w)
data_w <- unstack(data_l)

数据的两种形状

只要在一列中存在分类变量,都可以将其看作是长型数据。在上例中iris的前四列可以看作是宽型数据,但最后两列可以看作是一个长型数据。可以根据Species变量将数据转为宽型。并得到各花种类的平均值。

subdata <- iris[,4:5]
data_w <- unstack(subdata)
colMeans(data_w)
##     setosa versicolor  virginica 
##      0.246      1.326      2.026

数据重塑计算

在实践中这种单纯的长宽格式互转并不多见,因为我们并不是需要不同的数据格式,而需要不同格式下的分析结果。在上例中我们先转换数据格式再计算分析结果,而更常见的是一步直接得到分析结果。此时我们需要的是更为强大的reshape2包。

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的输出格式和功能在多维情况下要方便很多。

数据重塑计算

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

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

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

数据重塑计算

melt和dcast正如同是铁匠的两种得力工具,melt可以看作是炼炉,负责融合数据,成为一个纯粹的长型。而dcast则可以看作是铁锤,负责重铸数据,使之成为需要的格式,同时加以分析。下面的例子就是将之前生成的数据进行汇总计算

dcast(data=iris_long,
      formula=Species~variable,
      value.var='value',fun=mean)
##      Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1     setosa        5.006       3.428        1.462       0.246
## 2 versicolor        5.936       2.770        4.260       1.326
## 3  virginica        6.588       2.974        5.552       2.026

小练习

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

dcast(tips,sex~.,value.var='tip',fun=mean)
##      sex        .
## 1 Female 2.833448
## 2   Male 3.089618

又或者,按sex和size变量划分数据,分别计算小费金额,可以观察到用餐人数越多时,小费相应给的越多,而且男性顾客一般会比女性顾客大方一点。

dcast(tips,sex~size,value.var='tip',fun=mean)
##      sex        1        2        3        4    5    6
## 1 Female 1.276667 2.528448 3.250000 4.021111 5.14 4.60
## 2   Male 1.920000 2.614184 3.476667 4.172143 3.75 5.85

dcast函数的使用前提

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

更复杂的需求

如果我们想同时计算出不同性别顾客的小费和总费用。但现有的数据集中并没有这种分类变量,怎么处理呢?

一种是笨一点的方法,将前面用过的方法用两次,然后合并这两个结果。但这种方法在多变量情况下并不好。

dcast(tips,sex~.,value.var='tip',fun=mean)
##      sex        .
## 1 Female 2.833448
## 2   Male 3.089618
dcast(tips,sex~.,value.var='total_bill',fun=mean)
##      sex        .
## 1 Female 18.05690
## 2   Male 20.74408

更复杂的需求

另一种推荐的方法就是使用前面提到的melt函数,先将数据融合成纯粹的长型数据,再用dcast重铸。

tips_melt <- melt(data = tips,
              id.vars=c('sex','smoker','time','size','day'))
dcast(data = tips_melt, sex ~ variable,  
          value.var='value',fun= mean)
##      sex total_bill      tip
## 1 Female   18.05690 2.833448
## 2   Male   20.74408 3.089618

更复杂的需求

要同时考虑不同性别和吸烟习惯的顾客给小费的相对例。

tips_mean <- dcast(data = tips_melt, sex+ smoker~ variable, fun= mean)
tips_mean$rate <- with(tips_mean,tip/total_bill)
tips_mean
##      sex smoker total_bill      tip      rate
## 1 Female     No   18.10519 2.773519 0.1531892
## 2 Female    Yes   17.97788 2.931515 0.1630623
## 3   Male     No   19.79124 3.113402 0.1573122
## 4   Male    Yes   22.28450 3.051167 0.1369188

在dcast函数中的公式同时考虑到了三个分类变量,在第二步计算了小费相对于总餐费的比率,可以清楚的看到,吸烟的女性顾客相对是最大方的,而吸烟的男性则是最小气的。

数据的拆分合并

合并两个数据框

按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')
##   id gender name
## 1  1     23 john
## 2  2     34  ken
## 3  3     41  tom

数据按变量拆分

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

iris_splited <- split(iris,f=iris$Species)
class(iris_splited)
## [1] "list"

数据按变量合并

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

unsplit(iris_splited,f=iris$Species)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 1            5.1         3.5          1.4         0.2     setosa
## 2            4.9         3.0          1.4         0.2     setosa
## 3            4.7         3.2          1.3         0.2     setosa
## 4            4.6         3.1          1.5         0.2     setosa
## 5            5.0         3.6          1.4         0.2     setosa
## 6            5.4         3.9          1.7         0.4     setosa
## 7            4.6         3.4          1.4         0.3     setosa
## 8            5.0         3.4          1.5         0.2     setosa
## 9            4.4         2.9          1.4         0.2     setosa
## 10           4.9         3.1          1.5         0.1     setosa
## 11           5.4         3.7          1.5         0.2     setosa
## 12           4.8         3.4          1.6         0.2     setosa
## 13           4.8         3.0          1.4         0.1     setosa
## 14           4.3         3.0          1.1         0.1     setosa
## 15           5.8         4.0          1.2         0.2     setosa
## 16           5.7         4.4          1.5         0.4     setosa
## 17           5.4         3.9          1.3         0.4     setosa
## 18           5.1         3.5          1.4         0.3     setosa
## 19           5.7         3.8          1.7         0.3     setosa
## 20           5.1         3.8          1.5         0.3     setosa
## 21           5.4         3.4          1.7         0.2     setosa
## 22           5.1         3.7          1.5         0.4     setosa
## 23           4.6         3.6          1.0         0.2     setosa
## 24           5.1         3.3          1.7         0.5     setosa
## 25           4.8         3.4          1.9         0.2     setosa
## 26           5.0         3.0          1.6         0.2     setosa
## 27           5.0         3.4          1.6         0.4     setosa
## 28           5.2         3.5          1.5         0.2     setosa
## 29           5.2         3.4          1.4         0.2     setosa
## 30           4.7         3.2          1.6         0.2     setosa
## 31           4.8         3.1          1.6         0.2     setosa
## 32           5.4         3.4          1.5         0.4     setosa
## 33           5.2         4.1          1.5         0.1     setosa
## 34           5.5         4.2          1.4         0.2     setosa
## 35           4.9         3.1          1.5         0.2     setosa
## 36           5.0         3.2          1.2         0.2     setosa
## 37           5.5         3.5          1.3         0.2     setosa
## 38           4.9         3.6          1.4         0.1     setosa
## 39           4.4         3.0          1.3         0.2     setosa
## 40           5.1         3.4          1.5         0.2     setosa
## 41           5.0         3.5          1.3         0.3     setosa
## 42           4.5         2.3          1.3         0.3     setosa
## 43           4.4         3.2          1.3         0.2     setosa
## 44           5.0         3.5          1.6         0.6     setosa
## 45           5.1         3.8          1.9         0.4     setosa
## 46           4.8         3.0          1.4         0.3     setosa
## 47           5.1         3.8          1.6         0.2     setosa
## 48           4.6         3.2          1.4         0.2     setosa
## 49           5.3         3.7          1.5         0.2     setosa
## 50           5.0         3.3          1.4         0.2     setosa
## 51           7.0         3.2          4.7         1.4 versicolor
## 52           6.4         3.2          4.5         1.5 versicolor
## 53           6.9         3.1          4.9         1.5 versicolor
## 54           5.5         2.3          4.0         1.3 versicolor
## 55           6.5         2.8          4.6         1.5 versicolor
## 56           5.7         2.8          4.5         1.3 versicolor
## 57           6.3         3.3          4.7         1.6 versicolor
## 58           4.9         2.4          3.3         1.0 versicolor
## 59           6.6         2.9          4.6         1.3 versicolor
## 60           5.2         2.7          3.9         1.4 versicolor
## 61           5.0         2.0          3.5         1.0 versicolor
## 62           5.9         3.0          4.2         1.5 versicolor
## 63           6.0         2.2          4.0         1.0 versicolor
## 64           6.1         2.9          4.7         1.4 versicolor
## 65           5.6         2.9          3.6         1.3 versicolor
## 66           6.7         3.1          4.4         1.4 versicolor
## 67           5.6         3.0          4.5         1.5 versicolor
## 68           5.8         2.7          4.1         1.0 versicolor
## 69           6.2         2.2          4.5         1.5 versicolor
## 70           5.6         2.5          3.9         1.1 versicolor
## 71           5.9         3.2          4.8         1.8 versicolor
## 72           6.1         2.8          4.0         1.3 versicolor
## 73           6.3         2.5          4.9         1.5 versicolor
## 74           6.1         2.8          4.7         1.2 versicolor
## 75           6.4         2.9          4.3         1.3 versicolor
## 76           6.6         3.0          4.4         1.4 versicolor
## 77           6.8         2.8          4.8         1.4 versicolor
## 78           6.7         3.0          5.0         1.7 versicolor
## 79           6.0         2.9          4.5         1.5 versicolor
## 80           5.7         2.6          3.5         1.0 versicolor
## 81           5.5         2.4          3.8         1.1 versicolor
## 82           5.5         2.4          3.7         1.0 versicolor
## 83           5.8         2.7          3.9         1.2 versicolor
## 84           6.0         2.7          5.1         1.6 versicolor
## 85           5.4         3.0          4.5         1.5 versicolor
## 86           6.0         3.4          4.5         1.6 versicolor
## 87           6.7         3.1          4.7         1.5 versicolor
## 88           6.3         2.3          4.4         1.3 versicolor
## 89           5.6         3.0          4.1         1.3 versicolor
## 90           5.5         2.5          4.0         1.3 versicolor
## 91           5.5         2.6          4.4         1.2 versicolor
## 92           6.1         3.0          4.6         1.4 versicolor
## 93           5.8         2.6          4.0         1.2 versicolor
## 94           5.0         2.3          3.3         1.0 versicolor
## 95           5.6         2.7          4.2         1.3 versicolor
## 96           5.7         3.0          4.2         1.2 versicolor
## 97           5.7         2.9          4.2         1.3 versicolor
## 98           6.2         2.9          4.3         1.3 versicolor
## 99           5.1         2.5          3.0         1.1 versicolor
## 100          5.7         2.8          4.1         1.3 versicolor
## 101          6.3         3.3          6.0         2.5  virginica
## 102          5.8         2.7          5.1         1.9  virginica
## 103          7.1         3.0          5.9         2.1  virginica
## 104          6.3         2.9          5.6         1.8  virginica
## 105          6.5         3.0          5.8         2.2  virginica
## 106          7.6         3.0          6.6         2.1  virginica
## 107          4.9         2.5          4.5         1.7  virginica
## 108          7.3         2.9          6.3         1.8  virginica
## 109          6.7         2.5          5.8         1.8  virginica
## 110          7.2         3.6          6.1         2.5  virginica
## 111          6.5         3.2          5.1         2.0  virginica
## 112          6.4         2.7          5.3         1.9  virginica
## 113          6.8         3.0          5.5         2.1  virginica
## 114          5.7         2.5          5.0         2.0  virginica
## 115          5.8         2.8          5.1         2.4  virginica
## 116          6.4         3.2          5.3         2.3  virginica
## 117          6.5         3.0          5.5         1.8  virginica
## 118          7.7         3.8          6.7         2.2  virginica
## 119          7.7         2.6          6.9         2.3  virginica
## 120          6.0         2.2          5.0         1.5  virginica
## 121          6.9         3.2          5.7         2.3  virginica
## 122          5.6         2.8          4.9         2.0  virginica
## 123          7.7         2.8          6.7         2.0  virginica
## 124          6.3         2.7          4.9         1.8  virginica
## 125          6.7         3.3          5.7         2.1  virginica
## 126          7.2         3.2          6.0         1.8  virginica
## 127          6.2         2.8          4.8         1.8  virginica
## 128          6.1         3.0          4.9         1.8  virginica
## 129          6.4         2.8          5.6         2.1  virginica
## 130          7.2         3.0          5.8         1.6  virginica
## 131          7.4         2.8          6.1         1.9  virginica
## 132          7.9         3.8          6.4         2.0  virginica
## 133          6.4         2.8          5.6         2.2  virginica
## 134          6.3         2.8          5.1         1.5  virginica
## 135          6.1         2.6          5.6         1.4  virginica
## 136          7.7         3.0          6.1         2.3  virginica
## 137          6.3         3.4          5.6         2.4  virginica
## 138          6.4         3.1          5.5         1.8  virginica
## 139          6.0         3.0          4.8         1.8  virginica
## 140          6.9         3.1          5.4         2.1  virginica
## 141          6.7         3.1          5.6         2.4  virginica
## 142          6.9         3.1          5.1         2.3  virginica
## 143          5.8         2.7          5.1         1.9  virginica
## 144          6.8         3.2          5.9         2.3  virginica
## 145          6.7         3.3          5.7         2.5  virginica
## 146          6.7         3.0          5.2         2.3  virginica
## 147          6.3         2.5          5.0         1.9  virginica
## 148          6.5         3.0          5.2         2.0  virginica
## 149          6.2         3.4          5.4         2.3  virginica
## 150          5.9         3.0          5.1         1.8  virginica

数据汇总

数据汇总:强大的plyr包

单纯的拆分数据是很少见的,多数情况下我们的目的是要计算拆分数据后的结果,如果能将上面的三个步骤合在一个步骤内完成,就并不一定需要split函数,只需要强大的plyr包就可以了。

ratio_fun <- function(x) {
    sum(x$tip)/sum(x$total_bill)
}


library(plyr)
ddply(.data=tips,             # 拆分计算的对象
      .variables='sex',       # 按照什么变量来拆分
      .fun=ratio_fun)         # 计算的函数
##      sex        V1
## 1 Female 0.1569178
## 2   Male 0.1489398
ddply(tips,.(sex), ratio_fun)
##      sex        V1
## 1 Female 0.1569178
## 2   Male 0.1489398

更复杂的汇总

ddply(tips, sex~smoker, ratio_fun)
##      sex smoker        V1
## 1 Female     No 0.1531892
## 2 Female    Yes 0.1630623
## 3   Male     No 0.1573122
## 4   Male    Yes 0.1369188

plyr包的主要函数: **ply

input \ output array dataframe list discarded
array aaply adply alply a_ply
dataframe daply ddply dlply d_ply
list laply ldply llply l_ply

ddply:输入数据框,输出数据框.

adply:输入数组,输出数据框.

其它辅助函数

each: 生成一系列函数值,组成向量

x <- rnorm(10)
each(max,min,median,sd)(x)
##        max        min     median         sd 
##  0.5976536 -1.4016734 -0.6243977  0.5456757

其它辅助函数

colwise: 对数据框的每一个满足条件的列做运算。

colwise(mean,is.numeric)(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1     5.843333    3.057333        3.758    1.199333

下一步学习

案例与练习

New York Knicks

下载纽约尼克斯队比赛数据Knicks.rda

load('Knicks.rda')
head(data)
##   season visiting               opponent win points opp
## 1  07-08        1    Cleveland Cavaliers   L    106 110
## 2  07-08        0 Minnesota Timberwolves   W     97  93
## 3  07-08        0         Denver Nuggets   W    119 112
## 4  07-08        0          Orlando Magic   L    102 112
## 5  07-08        0             Miami Heat   L     72  75
## 6  07-08        1           Phoenix Suns   L    102 113

要回答的问题

1. 每个赛季的胜率?

2. 每个赛季的客场胜率?

3. 每个赛季的平均得分?

4. 每个赛季的本方和对的手平均得分?

5. 哪个对手是最强的?