R reshape2 转换数据教程

这篇博客介绍了R语言中reshape2包的功能,主要用于数据的宽格式和长格式转换。reshape2包含melt和cast两个关键函数,melt将宽格式转换为长格式,cast则反之。文中通过airquality数据集展示了如何使用这两个函数,并讨论了在转换过程中可能遇到的问题,如数据聚合和缺失值处理。此外,还强调了在数据分析中选择合适数据格式的重要性。
摘要由CSDN通过智能技术生成

reshape2是有Hadley Wickham 写的包,可以容易在宽和长两种格式间转换数据。

1. 长宽数据格式

  • 宽数据格式
    宽数据格式种每个变量对应一列,举例:
##      ozone      wind     temp
## 1 23.61538 11.622581 65.54839
## 2 29.44444 10.266667 79.10000
## 3 59.11538  8.941935 83.90323
## 4 59.96154  8.793548 83.96774
  • 长数据格式
    没有id(标识)变量,所有度量变量在使用列上;
##    variable     value
## 1     ozone 23.615385
## 2     ozone 29.444444
## 3     ozone 59.115385
## 4     ozone 59.961538
## 5      wind 11.622581
## 6      wind 10.266667
## 7      wind  8.941935
## 8      wind  8.793548
## 9      temp 65.548387
## 10     temp 79.100000
## 11     temp 83.903226
## 12     temp 83.967742

长格式数据有一列作为可能的变量类型,另一列作为哪些变量的值。长格式不是必须仅有两列,举例,可能有对某年种每天的ozone度量,这时则会增加表示天的列,即有不同长度级别。具体需要什么数据形状依赖你的业务要求。

事实证明,对于某些类型的数据分析,您需要宽格式数据,而对于其他类型的数据,则需要长格式数据。实际应用种,长格式数据较宽格式应用更多,举例,ggplot2需要长格式数据(lm(),glm(),gam()),但对于用户来说宽格式更易阅读。

2. reshape2 包

reshape2主要使用两个关键函数:melt 和 cast:

  • melt 把宽格式转成长格式
  • cast 把长格式转为宽格式

想象下金属:如果你熔化金属,它会滴下来变长。如果你把它倒入模子里,它就会变宽。

2.1 使用melt函数从宽转为长格式

下面示例使用 airquality 内置数据集。首先改变列名称为小写:

names(airquality) <- tolower(names(airquality))
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

首先我们使用缺省参数运行melt函数会生成什么数据?

aql <- melt(airquality)
## No id variables; using all as measure variables
head(aql)
##   variable value
## 1    ozone    41
## 2    ozone    36
## 3    ozone    12
## 4    ozone    18
## 5    ozone    NA
## 6    ozone    28

tail(aql)
##     variable value
## 913      day    25
## 914      day    26
## 915      day    27
## 916      day    28
## 917      day    29
## 918      day    30

缺省情况下,melt认为所有数值列都是变量值,通常没有问题。但我们现在需要每monthday 下的 ozone, solar.r, wind, 和 temp。这时我们通过id.vars指定monthday,id标识变量是用于标识每行数据。

aql <- melt(airquality, id.vars = c("month", "day"))
head(aql)
##   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

如果需要修改长数据格式列名称,可以使用其他参数:

aql <- melt(airquality, id.vars = c("month", "day"),
                        variable.name = "climate_variable", 
                        value.name = "climate_value")
head(aql)
##   month day climate_variable climate_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

2.2 使用cast函数从长转为宽格式

从宽到长格式转换相当直接,但长到宽稍微有点复杂。除了最简单的情况,它通常涉及一些尝试和错误。下面通过几个示例进行说明。

在reshape2种有多个cast函数。通常遇到最多的数据格式为data.frame对象,首先我们看dcast函数,另外 acast 返回 vector,matrix或array。

让我们把 airquality 转成不同的宽数据格式。首先回复数据格式并使用dcast函数进行转换,比较两者的差异。

dcast 使用公式描述数据形状。参数左边为标识变量,右边是度量变量。
刚开始要想找到正确的公式需要反复尝试并会出错。所以如果你遇到错误时,不要气馁,通常有多种方法可以写出这个公式。

library(reshape2)
aql <- melt(airquality, id.vars = c("month", "day"))
aqw <- dcast(aql, month + day ~ variable)
head(aqw)
##   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

## 查看原始数据进行对比
head(airquality) # original data
##   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

这里告诉dcast,month和day是标识变量,variable作为度量。因为仅保留有一列,dcast会计算其包含的值列表。我们页可以显示声明 values.var,有些场景必须要如此。

ok,除了顺序不同,我们成功恢复了数据。

如果还没有完全明白,我们可以看下图:
在这里插入图片描述

上图描述dcast函数,蓝色底纹表示id标识变量,作为行标识。红色底纹表示将转换为列名的变量,灰色表示要填充至单元格的数据值。

我们在转换数据集实战中通常遇到的错误是每个单元格有超过一个值,举例:我们把ID变量的day变量去掉:

dcast(aql, month ~ variable)

## Aggregation function missing: defaulting to length

##   month ozone solar.r wind temp
## 1     5    31      31   31   31
## 2     6    30      30   30   30
## 3     7    31      31   31   31
## 4     8    31      31   31   31
## 5     9    30      30   30   30

运行出现警告:缺少聚集函数。
如果看输出,单元格填充每个月合并数据,我们看到结果显示的月的天数。因此,当转换数据有多个值放入一个单元格时,需要明确如何聚合数据,如,mean,median或sum函数。

2.3 cast函数的聚合参数

下面我们再看一个示例,但这次我们计算平均值,同时指定na.rm=TRUE选项删除NA值:

dcast(aql, month ~ variable, fun.aggregate = mean, 
  na.rm = TRUE)
##   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

3. 总结

与melt不同,dcast还可以做一些其他有趣的事情,读者可以查看帮助文件进行学习

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值