数据-R语言-图表-决策-Linux-Python数据科学与R语言玩转大数据

利用reshape2包进行数据逆透视和数据透视

2017-09-17  本文已影响473人  鸣人吃土豆

我们在数据分析的过程中经常会碰到不适合分析的数据格式,有的时候我们需要要画图或者建立n重交叉分析表,需要将长数据透视成宽数据;而有的时候宽数据不利于我们进行后续的分析,需要将数据转换成长数据。那什么是宽数据,什么是长数据呢?下面我们举个栗子看看吧。

> library(openxlsx)
> data = read.xlsx("/Users/afei/Desktop/test.xlsx")
> head(data)
  组别 1月份 2月份 3月份 4月份 5月份 6月份
1 一组 40589 46475 54354 46497 40231 45402
2 二组 49351 54296 42200 47931 39243 41578
3 三组 41983 53099 39552 48860 53591 41799
4 四组 53883 52806 46719 38767 47856 42595
5 五组 41859 46403 45893 43950 51762 50848
6 六组 40231 48046 44355 49756 44490 50003
  组别  月份 value
1 一组 1月份 40589
2 二组 1月份 49351
3 三组 1月份 41983
4 四组 1月份 53883
5 五组 1月份 41859
6 六组 1月份 40231

下面我们就来看看reshape2包里面可以转变长宽的两个非常重要的函数

1.melt

melt是一个泛型函数,在reshape2包中有分别用于数据框、数组和列表的melt方法。下面简单介绍各个参数。

melt(data,id.vars,measure.vars,variable.name='variable',...,na.rm=FALSE,value.name='value',factorAsStrings=TRUE)
参数 描述 默认值
data 要溶解的数据框
id.vars ID变量(用于标识观察的变量) 所有非测量变量。如果id.vars和measure.vars都没有设置,默认会使用所有的因子变量和字符变量
measure.vars 测量变量(用于描述所测量的事物的变量) 所有非ID变量。如果id.vars和measure.vars都没有设置,默认会使用所有的非因子和非字符变量
variable.name 用于保存原始变量名的变量的名称 "variable"
value.name 用于保存原始值的名称 "value"
na.rm 告诉melt如何处理NA值 FALSE
factorAsStrings 告诉melt是否要将字符变量转化成因子 TRUE

参数解释:

参数 描述 默认值
data 要溶解的数据框
id.vars ID变量(用于标识观察的变量) 所有非测量变量。如果id.vars和measure.vars都没有设置,默认会使用所有的因子变量和字符变量
measure.vars 测量变量(用于描述所测量的事物的变量) 所有非ID变量。如果id.vars和measure.vars都没有设置,默认会使用所有的非因子和非字符变量
variable.name 用于保存原始变量名的变量的名称 "variable"
value.name 用于保存原始值的名称 "value"
na.rm 告诉melt如何处理NA值 FALSE
factorAsStrings 告诉melt是否要将字符变量转化成因子 TRUE

(1)只带有data参数的情况
我们可以看到如果id.vars和measure.vars都没有设置,默认会使用所有的因子变量和字符变量作为ID变量,使用所有的非因子和非字符变量作为测量变量

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

> test <- melt(iris)
Using Species as id variables
> head(test)
  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参数的情况

> 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

> test2 <- melt(airquality,id.vars = c("Month","Day"))
> head(test2)
  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

(3)使用measure.vars的情况

> 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

> test3 <- melt(airquality,id.vars = c("Month","Day"),measure.vars = "Ozone")
> head(test3)
  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

> tail(test3)
    Month Day variable value
148     9  25    Ozone    14
149     9  26    Ozone    30
150     9  27    Ozone    NA
151     9  28    Ozone    14
152     9  29    Ozone    18
153     9  30    Ozone    20

(4)使用variable.name和value.name的情况

> 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
> test4 <- melt(airquality,id.vars = c("Month","Day"),measure.vars = c("Ozone","Temp"),variable.name="xixi",value.name = "haha")
> head(test4)
  Month Day  xixi haha
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
> tail(test4)
    Month Day xixi haha
301     9  25 Temp   63
302     9  26 Temp   70
303     9  27 Temp   77
304     9  28 Temp   75
305     9  29 Temp   76
306     9  30 Temp   68

2.cast

cast函数在reshape2包中有好几个版本

dcast公式

dcast(data, formula, fun.aggregate = NULL, ..., margins = NULL,subset = NULL, fill = NULL, drop = TRUE,value.var = guess_value(data))
参数 描述 默认值
data 以溶解的数据框(通常是melt函数创建的)
formula 描述输出结果的公式,比如x~y,则x表示数据透视表的行,y代表数据透视表的列
fun.aggregate 聚合函数。如果要聚合输出结果中一溶解的数据,用这个参数可以设置聚合函数。可以使用自定义函数. NULL
margins 相当于透视表中的行总计和列总计 NULL
subset 选取满足一些特定值的数据,相当于Excel透视表的筛选。例如, subset =.(variable ==“length”) NULL

参数说明

参数 描述 默认值
data 以溶解的数据框(通常是melt函数创建的)
formula 描述输出结果的公式,比如x~y,则x表示数据透视表的行,y代表数据透视表的列
fun.aggregate 聚合函数。如果要聚合输出结果中一溶解的数据,用这个参数可以设置聚合函数。可以使用自定义函数. NULL
margins 相当于透视表中的行总计和列总计 NULL
subset 选取满足一些特定值的数据,相当于Excel透视表的筛选。例如, subset =.(variable ==“length”) NULL

例子说明

> names(airquality) <- tolower(names(airquality))
> aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)
> head(aqm)
  month day variable value
1     5   1    ozone    41
2     5   2    ozone    36
3     5   3    ozone    12
4     5   4    ozone    18
6     5   6    ozone    28
7     5   7    ozone    23
-----------------------------------------------------------------
**计算按月份分组的每个变量的均值**
> dcast(aqm, month ~ variable, mean, margins = c("month", "variable"),na.rm=TRUE)
  month    ozone  solar.r      wind     temp    (all)
1     5 23.61538 181.2963 11.622581 65.54839 68.70696
2     6 29.44444 190.1667 10.266667 79.10000 87.38384
3     7 59.11538 216.4839  8.941935 83.90323 93.49748
4     8 59.96154 171.8571  8.793548 83.96774 79.71207
5     9 31.44828 167.4333 10.180000 76.90000 71.82689
6 (all) 42.12931 185.9315  9.957516 77.88235 80.05722
-----------------------------------------------------------------
**和上面的例子对调了一下行和列**
> dcast(aqm, variable ~ month, mean, margins = c("month", "variable"))
  variable         5         6          7          8         9      (all)
1    ozone  23.61538  29.44444  59.115385  59.961538  31.44828  42.129310
2  solar.r 181.29630 190.16667 216.483871 171.857143 167.43333 185.931507
3     wind  11.62258  10.26667   8.941935   8.793548  10.18000   9.957516
4     temp  65.54839  79.10000  83.903226  83.967742  76.90000  77.882353
5    (all)  68.70696  87.38384  93.497479  79.712069  71.82689  80.057218
-----------------------------------------------------------------
> names(airquality) <- tolower(names(airquality))
> aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)
> head(aqm)
  month day variable value
1     5   1    ozone    41
2     5   2    ozone    36
3     5   3    ozone    12
4     5   4    ozone    18
6     5   6    ozone    28
7     5   7    ozone    23
> acast(aqm,day~month~variable)
, , ozone

     5  6   7   8  9
1   41 NA 135  39 96
2   36 NA  49   9 78
3   12 NA  32  16 73
4   18 NA  NA  78 91
5   NA NA  64  35 47
6   28 NA  40  66 32
7   23 29  77 122 20
8   19 NA  97  89 23
9    8 71  97 110 21
10  NA 39  85  NA 24
11   7 NA  NA  NA 44
12  16 NA  10  44 21
13  11 23  27  28 28
14  14 NA  NA  65  9
15  18 NA   7  NA 13
16  14 21  48  22 46
17  34 37  35  59 18
18   6 20  61  23 13
19  30 12  79  31 24
20  11 13  63  44 16
21   1 NA  16  21 13
22  11 NA  NA   9 23
23   4 NA  NA  NA 36
24  32 NA  80  45  7
25  NA NA 108 168 14
26  NA NA  20  73 30
27  NA NA  52  NA NA
28  23 NA  82  76 14
29  45 NA  50 118 18
30 115 NA  64  84 20
31  37 NA  59  85 NA

, , solar.r

     5   6   7   8   9
1  190 286 269  83 167
2  118 287 248  24 197
3  149 242 236  77 183
4  313 186 101  NA 189
5   NA 220 175  NA  95
6   NA 264 314  NA  92
7  299 127 276 255 252
8   99 273 267 229 220
9   19 291 272 207 230
10 194 323 175 222 259
11  NA 259 139 137 236
12 256 250 264 192 259
13 290 148 175 273 238
14 274 332 291 157  24
15  65 322  48  64 112
16 334 191 260  71 237
17 307 284 274  51 224
18  78  37 285 115  27
19 322 120 187 244 238
20  44 137 220 190 201
21   8 150   7 259 238
22 320  59 258  36  14
23  25  91 295 255 139
24  92 250 294 212  49
25  66 135 223 238  20
26 266 127  81 215 193
27  NA  47  82 153 145
28  13  98 213 203 191
29 252  31 275 225 131
30 223 138 253 237 223
31 279  NA 254 188  NA

, , wind

      5    6    7    8    9
1   7.4  8.6  4.1  6.9  6.9
2   8.0  9.7  9.2 13.8  5.1
3  12.6 16.1  9.2  7.4  2.8
4  11.5  9.2 10.9  6.9  4.6
5  14.3  8.6  4.6  7.4  7.4
6  14.9 14.3 10.9  4.6 15.5
7   8.6  9.7  5.1  4.0 10.9
8  13.8  6.9  6.3 10.3 10.3
9  20.1 13.8  5.7  8.0 10.9
10  8.6 11.5  7.4  8.6  9.7
11  6.9 10.9  8.6 11.5 14.9
12  9.7  9.2 14.3 11.5 15.5
13  9.2  8.0 14.9 11.5  6.3
14 10.9 13.8 14.9  9.7 10.9
15 13.2 11.5 14.3 11.5 11.5
16 11.5 14.9  6.9 10.3  6.9
17 12.0 20.7 10.3  6.3 13.8
18 18.4  9.2  6.3  7.4 10.3
19 11.5 11.5  5.1 10.9 10.3
20  9.7 10.3 11.5 10.3  8.0
21  9.7  6.3  6.9 15.5 12.6
22 16.6  1.7  9.7 14.3  9.2
23  9.7  4.6 11.5 12.6 10.3
24 12.0  6.3  8.6  9.7 10.3
25 16.6  8.0  8.0  3.4 16.6
26 14.9  8.0  8.6  8.0  6.9
27  8.0 10.3 12.0  5.7 13.2
28 12.0 11.5  7.4  9.7 14.3
29 14.9 14.9  7.4  2.3  8.0
30  5.7  8.0  7.4  6.3 11.5
31  7.4   NA  9.2  6.3   NA

, , temp

    5  6  7  8  9
1  67 78 84 81 91
2  72 74 85 81 92
3  74 67 81 82 93
4  62 84 84 86 93
5  56 85 83 85 87
6  66 79 83 87 84
7  65 82 88 89 80
8  59 87 92 90 78
9  61 90 92 90 75
10 69 87 89 92 73
11 74 93 82 86 81
12 69 92 73 86 76
13 66 82 81 82 77
14 68 80 91 80 71
15 58 79 80 79 71
16 64 77 81 77 78
17 66 72 82 79 67
18 57 65 84 76 76
19 68 73 87 78 68
20 62 76 85 78 82
21 59 77 74 77 64
22 73 76 81 72 71
23 61 76 82 75 81
24 61 76 86 79 69
25 57 75 85 81 63
26 58 78 82 86 70
27 57 73 86 88 77
28 67 80 88 97 75
29 81 77 86 94 76
30 79 83 83 96 68
31 76 NA 81 94 NA
-----------------------------------------------------------------
**加margins参数的情况**
**注意acast和dcast函数之间的区别**
> acast(aqm,month~variable,mean)
     ozone  solar.r      wind     temp
5 23.61538 181.2963 11.622581 65.54839
6 29.44444 190.1667 10.266667 79.10000
7 59.11538 216.4839  8.941935 83.90323
8 59.96154 171.8571  8.793548 83.96774
9 31.44828 167.4333 10.180000 76.90000

> acast(aqm, month ~ variable, mean, margins = TRUE)
         ozone  solar.r      wind     temp    (all)
5     23.61538 181.2963 11.622581 65.54839 68.70696
6     29.44444 190.1667 10.266667 79.10000 87.38384
7     59.11538 216.4839  8.941935 83.90323 93.49748
8     59.96154 171.8571  8.793548 83.96774 79.71207
9     31.44828 167.4333 10.180000 76.90000 71.82689
(all) 42.12931 185.9315  9.957516 77.88235 80.05722

> dcast(aqm,month~variable,mean)
  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

> dcast(aqm,month~variable,mean,margins=TRUE)
  month    ozone  solar.r      wind     temp    (all)
1     5 23.61538 181.2963 11.622581 65.54839 68.70696
2     6 29.44444 190.1667 10.266667 79.10000 87.38384
3     7 59.11538 216.4839  8.941935 83.90323 93.49748
4     8 59.96154 171.8571  8.793548 83.96774 79.71207
5     9 31.44828 167.4333 10.180000 76.90000 71.82689
6 (all) 42.12931 185.9315  9.957516 77.88235 80.05722

> dcast(aqm, month ~ variable, mean, margins = c("month", "variable"))
  month    ozone  solar.r      wind     temp    (all)
1     5 23.61538 181.2963 11.622581 65.54839 68.70696
2     6 29.44444 190.1667 10.266667 79.10000 87.38384
3     7 59.11538 216.4839  8.941935 83.90323 93.49748
4     8 59.96154 171.8571  8.793548 83.96774 79.71207
5     9 31.44828 167.4333 10.180000 76.90000 71.82689
6 (all) 42.12931 185.9315  9.957516 77.88235 80.05722
-----------------------------------------------------------------
**使用subset参数的情况**
> library(plyr) #为了使用.函数
> dcast(aqm,variable~month,mean)
  variable         5         6          7          8         9
1    ozone  23.61538  29.44444  59.115385  59.961538  31.44828
2  solar.r 181.29630 190.16667 216.483871 171.857143 167.43333
3     wind  11.62258  10.26667   8.941935   8.793548  10.18000
4     temp  65.54839  79.10000  83.903226  83.967742  76.90000

> dcast(aqm,variable~month,mean,subset=.(variable=="ozone"))
  variable        5        6        7        8        9
1    ozone 23.61538 29.44444 59.11538 59.96154 31.44828

> dcast(aqm,variable~month,mean,subset=.(month==5))
  variable         5
1    ozone  23.61538
2  solar.r 181.29630
3     wind  11.62258
4     temp  65.54839

> dcast(aqm,variable~month,mean,subset=.(variable=="ozone" & month==5))
  variable        5
1    ozone 23.61538

-----------------------------------------------------------------
**n重交叉分析表**
> names(ChickWeight) <- tolower(names(ChickWeight))
> chick_m <- melt(ChickWeight, id=2:4, na.rm=TRUE)
> 
> head(chick_m)
  time chick diet variable value
1    0     1    1   weight    42
2    2     1    1   weight    51
3    4     1    1   weight    59
4    6     1    1   weight    64
5    8     1    1   weight    76
6   10     1    1   weight    93
> head(ChickWeight)
  weight time chick diet
1     42    0     1    1
2     51    2     1    1
3     59    4     1    1
4     64    6     1    1
5     76    8     1    1
6     93   10     1    1

> head(dcast(chick_m,diet+chick~time))
  diet chick  0  2  4  6  8 10 12 14 16  18  20  21
1    1    18 39 35 NA NA NA NA NA NA NA  NA  NA  NA
2    1    16 41 45 49 51 57 51 54 NA NA  NA  NA  NA
3    1    15 41 49 56 64 68 68 67 68 NA  NA  NA  NA
4    1    13 41 48 53 60 65 67 71 70 71  81  91  96
5    1     9 42 51 59 68 85 96 90 92 93 100 100  98
6    1    20 41 47 54 58 65 73 77 89 98 107 115 117

> head(dau.user.info)
    log_date app_name user_id install_date gender generation device_type
1 2013-08-01  game-01   33754   2013-08-01      M         20         iOS
2 2013-08-01  game-01   28598   2013-07-16      M         50         iOS
3 2013-08-01  game-01   30306   2013-07-20      F         30         iOS
4 2013-08-01  game-01     117   2013-04-17      F         20         iOS
5 2013-08-01  game-01    6605   2013-05-02      M         20         iOS
6 2013-08-01  game-01     346   2013-04-18      F         30         iOS
  log_month
1   2013-08
2   2013-08
3   2013-08
4   2013-08
5   2013-08
6   2013-08
> dcast(dau.user.info,log_month~gender+generation,value.var = "user_id",length)
  log_month F_10  F_20  F_30 F_40 F_50 M_10  M_20  M_30 M_40 M_50
1   2013-08 9091 17181 14217 4597 2257 9694 16490 13855 4231 2572
2   2013-09 7316 13616 11458 3856 1781 8075 13613 10768 3638 2054


------------------------------分割线-----------------------------------

下面介绍一下reshape包中的cast函数
reshape包和reshape2包都是同一个人开发的,所以melt和cast函数大同小异

**生成数据**
> states <- data.frame(state=row.names(state.x77),region=state.region,state.x77,row.names=1:50)
> head(states)
       state region Population Income Illiteracy Life.Exp Murder HS.Grad
1    Alabama  South       3615   3624        2.1    69.05   15.1    41.3
2     Alaska   West        365   6315        1.5    69.31   11.3    66.7
3    Arizona   West       2212   4530        1.8    70.55    7.8    58.1
4   Arkansas  South       2110   3378        1.9    70.66   10.1    39.9
5 California   West      21198   5114        1.1    71.71   10.3    62.6
6   Colorado   West       2541   4884        0.7    72.06    6.8    63.9
  Frost   Area
1    20  50708
2   152 566432
3    15 113417
4    65  51945
5    20 156361
6   166 103766
-----------------------------------------------------------------
**融合数据**
> test <- melt(states)
Using state, region as id variables
> head(test)
       state region   variable value
1    Alabama  South Population  3615
2     Alaska   West Population   365
3    Arizona   West Population  2212
4   Arkansas  South Population  2110
5 California   West Population 21198
6   Colorado   West Population  2541
-----------------------------------------------------------------
**使用自定义函数**
fun <- function(x){
  require('fBasics')
  n = sum(!is.na(x))
  nmiss = sum(is.na(x))
  m=mean(x,na.rm = TRUE)
  s = sd(x,na.rm = TRUE)
  max = max(x,na.rm = TRUE)
  min = min(x,na.rm=TRUE)
  return(c(nomiss = n,miss=nmiss,mean=m,sd=s,max=max,min=min))
}

> library(reshape)
> cast(test,variable~.|Species,fun) #将输出结果设置为列表格式(加了.|,dcast好像不能这样写) 
$setosa
      variable nomiss miss  mean        sd max min
1 Sepal.Length     50    0 5.006 0.3524897 5.8 4.3
2  Sepal.Width     50    0 3.428 0.3790644 4.4 2.3
3 Petal.Length     50    0 1.462 0.1736640 1.9 1.0
4  Petal.Width     50    0 0.246 0.1053856 0.6 0.1

$versicolor
      variable nomiss miss  mean        sd max min
1 Sepal.Length     50    0 5.936 0.5161711 7.0 4.9
2  Sepal.Width     50    0 2.770 0.3137983 3.4 2.0
3 Petal.Length     50    0 4.260 0.4699110 5.1 3.0
4  Petal.Width     50    0 1.326 0.1977527 1.8 1.0

$virginica
      variable nomiss miss  mean        sd max min
1 Sepal.Length     50    0 6.588 0.6358796 7.9 4.9
2  Sepal.Width     50    0 2.974 0.3224966 3.8 2.2
3 Petal.Length     50    0 5.552 0.5518947 6.9 4.5
4  Petal.Width     50    0 2.026 0.2746501 2.5 1.4
-----------------------------------------------------------------
**多变量分组统计**
> data <- data.frame(x=rpois(100,2),y=rpois(100,3),z=runif(100,10,20))
> head(data)
  x y        z
1 2 3 19.39958
2 1 3 13.69048
3 3 4 10.29499
4 2 3 10.67246
5 2 1 19.03233
6 3 2 19.79894

> m_data <- melt(data,measure.vars="z")

**dcast也做不了c(mean,min,max,median)**
> head(cast(m_data,x+y~variable,c(mean,min,max,median)))
  x y   z_mean    z_min    z_max z_median
1 0 0 14.87159 14.87159 14.87159 14.87159
2 0 1 16.43556 12.88235 19.98877 16.43556
3 0 2 14.92238 10.99968 19.55458 14.56764
4 0 3 15.14760 12.90916 16.56199 15.26421
5 0 4 14.65345 12.75043 16.55647 14.65345
6 0 5 11.07558 11.07558 11.07558 11.07558
上一篇 下一篇

猜你喜欢

热点阅读