前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「R」使用reshape2包

「R」使用reshape2包

作者头像
王诗翔呀
发布2020-07-03 11:19:57
5560
发布2020-07-03 11:19:57
举报
文章被收录于专栏:优雅R优雅R

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

注:现在大部分时间我们都在使用 tidyr 提供的长宽格式转换工具,比 reshape2 包提供的操作更容易理解。

熔解与铸造

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

使用例子

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

代码语言:javascript
复制
# 使用数据展示
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两个变量唯一确定数据的一行。

代码语言:javascript
复制
# 导入包
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的变量都没有改变,而其他变量都变成一个新生变量的值,另外一列变量记录对应的数值结果。

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

代码语言:javascript
复制
melt(data, id.vars, measure.vars,
  variable.name = "variable", ..., na.rm = FALSE, value.name = "value",
  factorsAsStrings = TRUE)
代码语言:javascript
复制
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()读取已熔解的数据,并使用你提供的一个公式和一个可选的整合数据的函数将其重铸。

公式形式如下:

代码语言:javascript
复制
rowvar1 + rowvar2 + ... ~ colvar1 + colvar2 + ...

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

代码语言:javascript
复制
# 对每月结果求平均
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实战

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 优雅R 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 熔解与铸造
    • 使用例子
      • 熔解
      • 铸造
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档