使用Reshape包

接上一篇笔记【r<-分析】分析之前,准备数据

很多R用户都搞不太清楚用于修整数据的内置函数(比如stackunstackreshape),庆幸的是我们还有其他选择,Hadley Wickham(ggplot2的作者)开发了一个reshape2库,用更直观的方式将数据修整为所需要的形式。

熔解与铸造

reshape库用一个直观的模型来描述如何操作数据表。Hadley发现,如果有详细的事项数据,就可以很方便地将这些数据转换成各种形式。通常,我们会拿到一个数据表,将其转换为一系列事项,然后将其修整为所需的格式。他将数据表转换成事项列表的过程称为熔解(melt),将事项列表转换成数据表的过程称为铸造(cast)

使用例子

我们用一个例子来看一下熔解与铸造究竟是怎么回事,以体会reshape2包的有用之处。

# 使用数据展示
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

熔解

数据集的熔解是将它重构为这样一种格式:每个观测变量独占一行,行中要带有唯一确定这个测量所需的标识变量

比如我们可以通过MonthDay两个变量唯一确定数据的一行。

# 导入包
library(reshape2)
md <- melt(airquality, id=c("Month", "Day"))
head(md, 20)
##    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
## 7      5   7    Ozone    23
## 8      5   8    Ozone    19
## 9      5   9    Ozone     8
## 10     5  10    Ozone    NA
## 11     5  11    Ozone     7
## 12     5  12    Ozone    16
## 13     5  13    Ozone    11
## 14     5  14    Ozone    14
## 15     5  15    Ozone    18
## 16     5  16    Ozone    14
## 17     5  17    Ozone    34
## 18     5  18    Ozone     6
## 19     5  19    Ozone    30
## 20     5  20    Ozone    11

可以发现,标为id的变量都没有改变,而其他变量都变成一个新生变量的值,另外一列变量记录对应的数值结果。

我们可以修改参数来更灵活地进行处理:

melt(data, id.vars, measure.vars,
  variable.name = "variable", ..., na.rm = FALSE, value.name = "value",
  factorsAsStrings = TRUE)
md <- melt(airquality, id.vars = c("Month", "Day"), value.name = "New_Value", variable.name = "Class")
head(md, 20)
##    Month Day Class New_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
## 7      5   7 Ozone        23
## 8      5   8 Ozone        19
## 9      5   9 Ozone         8
## 10     5  10 Ozone        NA
## 11     5  11 Ozone         7
## 12     5  12 Ozone        16
## 13     5  13 Ozone        11
## 14     5  14 Ozone        14
## 15     5  15 Ozone        18
## 16     5  16 Ozone        14
## 17     5  17 Ozone        34
## 18     5  18 Ozone         6
## 19     5  19 Ozone        30
## 20     5  20 Ozone        11

一旦我们拥有融合后的数据,就可以使用dcast()将它铸造为任意形状。

铸造

dcast()读取已熔解的数据,并使用你提供的一个公式和一个可选的整合数据的函数将其重铸。

公式形式如下:

rowvar1 + rowvar2 + ... ~ colvar1 + colvar2 + ...

在这个公式中,~左边定义了要划掉的变量集合,以确定各行的内容,而右边定义要划掉、确定各列内容的变量集合。

# 对每月结果求平均
dcast(md, Month ~ Class, mean)
## Using New_Value as value column: use value.var to override.
##   Month Ozone Solar.R  Wind Temp
## 1     5    NA      NA 11.62 65.5
## 2     6    NA     190 10.27 79.1
## 3     7    NA     216  8.94 83.9
## 4     8    NA      NA  8.79 84.0
## 5     9    NA     167 10.18 76.9

# 对每天的所有变量结果求平均
dcast(md, Month ~ Day, mean)
## Using New_Value as value column: use value.var to override.
##   Month     1    2    3     4    5     6     7     8     9    10 11   12
## 1     5  76.3 58.5 61.9 101.1   NA    NA  98.9  47.7  27.0    NA NA 87.7
## 2     6    NA   NA   NA    NA   NA    NA  61.9    NA 116.5 115.1 NA   NA
## 3     7 123.0 97.8 89.5    NA 81.7 112.0 111.5 115.6 116.7  89.1 NA 90.3
## 4     8  52.5 31.9 45.6    NA   NA    NA 117.5 104.6 103.8    NA NA 83.4
## 5     9  90.2 93.0 88.0  94.4 59.1  55.9  90.7  82.8  84.2  91.4 94 92.9
##     13   14   15    16    17    18    19   20   21    22   23    24    25
## 1 94.0 91.7 38.5 105.9 104.8  39.9 107.9 31.7 19.4 105.2 24.9  49.2    NA
## 2 65.2   NA   NA  76.0 103.4  32.8  54.1 59.1   NA    NA   NA    NA    NA
## 3 74.5   NA 37.3  99.0 100.3 109.1  89.5 94.9 26.0    NA   NA 117.2 106.0
## 4 98.6 77.9   NA  45.1  48.8  55.4  91.0 80.6 93.1  32.8   NA  86.4 122.6
## 5 87.3 28.7 51.9  92.0  80.7  31.6  85.1 76.8 81.9  29.3 66.6  33.8  28.4
##     26 27   28    29    30    31
## 1   NA NA 28.8  98.2 105.7  99.8
## 2   NA NA   NA    NA    NA   NaN
## 3 47.9 58 97.6 104.6 101.8 100.8
## 4 95.5 NA 96.4 109.8 105.8  93.3
## 5 75.0 NA 73.6  58.2  80.6   NaN

# 变回原来的
dcast(md, Month + Day ~ Class)
## Using New_Value as value column: use value.var to override.
##     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
## 7       5   7    23     299  8.6   65
## 8       5   8    19      99 13.8   59
## 9       5   9     8      19 20.1   61
## 10      5  10    NA     194  8.6   69
## 11      5  11     7      NA  6.9   74
## 12      5  12    16     256  9.7   69
## 13      5  13    11     290  9.2   66
## 14      5  14    14     274 10.9   68
## 15      5  15    18      65 13.2   58
## 16      5  16    14     334 11.5   64
## 17      5  17    34     307 12.0   66
## 18      5  18     6      78 18.4   57
## 19      5  19    30     322 11.5   68
## 20      5  20    11      44  9.7   62
## 21      5  21     1       8  9.7   59
## 22      5  22    11     320 16.6   73
## 23      5  23     4      25  9.7   61
## 24      5  24    32      92 12.0   61
## 25      5  25    NA      66 16.6   57
## 26      5  26    NA     266 14.9   58
## 27      5  27    NA      NA  8.0   57
## 28      5  28    23      13 12.0   67
## 29      5  29    45     252 14.9   81
## 30      5  30   115     223  5.7   79
## 31      5  31    37     279  7.4   76
## 32      6   1    NA     286  8.6   78
## 33      6   2    NA     287  9.7   74
## [到达getOption("max.print") -- 略过120行]]

#
dcast(md, Month+Class ~ Day)
## Using New_Value as value column: use value.var to override.
##    Month   Class     1     2     3     4     5     6     7     8     9
## 1      5   Ozone  41.0  36.0  12.0  18.0    NA  28.0  23.0  19.0   8.0
## 2      5 Solar.R 190.0 118.0 149.0 313.0    NA    NA 299.0  99.0  19.0
## 3      5    Wind   7.4   8.0  12.6  11.5  14.3  14.9   8.6  13.8  20.1
## 4      5    Temp  67.0  72.0  74.0  62.0  56.0  66.0  65.0  59.0  61.0
## 5      6   Ozone    NA    NA    NA    NA    NA    NA  29.0    NA  71.0
## 6      6 Solar.R 286.0 287.0 242.0 186.0 220.0 264.0 127.0 273.0 291.0
##       10    11    12    13    14    15    16    17    18    19    20    21
## 1     NA   7.0  16.0  11.0  14.0  18.0  14.0  34.0   6.0  30.0  11.0   1.0
## 2  194.0    NA 256.0 290.0 274.0  65.0 334.0 307.0  78.0 322.0  44.0   8.0
## 3    8.6   6.9   9.7   9.2  10.9  13.2  11.5  12.0  18.4  11.5   9.7   9.7
## 4   69.0  74.0  69.0  66.0  68.0  58.0  64.0  66.0  57.0  68.0  62.0  59.0
## 5   39.0    NA    NA  23.0    NA    NA  21.0  37.0  20.0  12.0  13.0    NA
## 6  323.0 259.0 250.0 148.0 332.0 322.0 191.0 284.0  37.0 120.0 137.0 150.0
##       22    23    24    25    26    27    28    29    30    31
## 1   11.0   4.0  32.0    NA    NA    NA  23.0  45.0 115.0  37.0
## 2  320.0  25.0  92.0  66.0 266.0    NA  13.0 252.0 223.0 279.0
## 3   16.6   9.7  12.0  16.6  14.9   8.0  12.0  14.9   5.7   7.4
## 4   73.0  61.0  61.0  57.0  58.0  57.0  67.0  81.0  79.0  76.0
## 5     NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
## 6   59.0  91.0 250.0 135.0 127.0  47.0  98.0  31.0 138.0    NA
## [到达getOption("max.print") -- 略过14行]]

# 
dcast(md, Month ~ Class + Day)
## Using New_Value as value column: use value.var to override.
##   Month Ozone_1 Ozone_2 Ozone_3 Ozone_4 Ozone_5 Ozone_6 Ozone_7 Ozone_8
## 1     5      41      36      12      18      NA      28      23      19
##   Ozone_9 Ozone_10 Ozone_11 Ozone_12 Ozone_13 Ozone_14 Ozone_15 Ozone_16
## 1       8       NA        7       16       11       14       18       14
##   Ozone_17 Ozone_18 Ozone_19 Ozone_20 Ozone_21 Ozone_22 Ozone_23 Ozone_24
## 1       34        6       30       11        1       11        4       32
##   Ozone_25 Ozone_26 Ozone_27 Ozone_28 Ozone_29 Ozone_30 Ozone_31 Solar.R_1
## 1       NA       NA       NA       23       45      115       37       190
##   Solar.R_2 Solar.R_3 Solar.R_4 Solar.R_5 Solar.R_6 Solar.R_7 Solar.R_8
## 1       118       149       313        NA        NA       299        99
##   Solar.R_9 Solar.R_10 Solar.R_11 Solar.R_12 Solar.R_13 Solar.R_14
## 1        19        194         NA        256        290        274
##   Solar.R_15 Solar.R_16 Solar.R_17 Solar.R_18 Solar.R_19 Solar.R_20
## 1         65        334        307         78        322         44
##   Solar.R_21 Solar.R_22 Solar.R_23 Solar.R_24 Solar.R_25 Solar.R_26
## 1          8        320         25         92         66        266
##   Solar.R_27 Solar.R_28 Solar.R_29 Solar.R_30 Solar.R_31 Wind_1 Wind_2
## 1         NA         13        252        223        279    7.4    8.0
##   Wind_3 Wind_4 Wind_5 Wind_6 Wind_7 Wind_8 Wind_9 Wind_10 Wind_11 Wind_12
## 1   12.6   11.5   14.3   14.9    8.6   13.8   20.1     8.6     6.9     9.7
##   Wind_13 Wind_14 Wind_15 Wind_16 Wind_17 Wind_18 Wind_19 Wind_20 Wind_21
## 1     9.2    10.9    13.2    11.5    12.0    18.4    11.5     9.7     9.7
##   Wind_22 Wind_23 Wind_24 Wind_25 Wind_26 Wind_27 Wind_28 Wind_29 Wind_30
## 1    16.6     9.7    12.0    16.6    14.9     8.0    12.0    14.9     5.7
##   Wind_31 Temp_1 Temp_2 Temp_3 Temp_4 Temp_5 Temp_6 Temp_7 Temp_8 Temp_9
## 1     7.4     67     72     74     62     56     66     65     59     61
##   Temp_10 Temp_11 Temp_12 Temp_13 Temp_14 Temp_15 Temp_16 Temp_17 Temp_18
## 1      69      74      69      66      68      58      64      66      57
##   Temp_19 Temp_20 Temp_21 Temp_22 Temp_23 Temp_24 Temp_25 Temp_26 Temp_27
## 1      68      62      59      73      61      61      57      58      57
##   Temp_28 Temp_29 Temp_30 Temp_31
## 1      67      81      79      76
## [到达getOption("max.print") -- 略过4行]]

参考:

R核心技术手册以及R实战

comments powered by Disqus