本文是对[Sean C. Anderson ][1] 所介绍的reshape2进行的整理。
宽数据
# ozone wind temp# 1 23.62 11.623 65.55# 2 29.44 10.267 79.10# 3 59.12 8.942 83.90# 4 59.96 8.794 83.97
长数据
# variable value# 1 ozone 23.615# 2 ozone 29.444# 3 ozone 59.115# 4 ozone 59.962# 5 wind 11.623# 6 wind 10.267# 7 wind 8.942# 8 wind 8.794# 9 temp 65.548# 10 temp 79.100# 11 temp 83.903# 12 temp 83.968
长数据有一列数据是变量的类型,有一列是变量的值。长数据不一定只有两列。ggplot2需要长类型的数据,plyr也需要长类型的数据,大多数的模型(比如lm()
, glm()
以及gam()
)也需要长数据。
reshape2 用得比较多的是melt
和cast
两个函数。
melt
函数对宽数据进行处理,得到长数据;cast
函数对长数据进行处理,得到宽数据;此处用R内置的airquality数据集,首先将列名改成小写,然后查看相应的数据
names(airquality) <- tolower(names(airquality))head(airquality)
ozone solar.r wind temp month day1 41 190 7.4 67 5 12 36 118 8.0 72 5 23 12 149 12.6 74 5 34 18 313 11.5 62 5 45 NA NA 14.3 56 5 56 28 NA 14.9 66 5 6
先看看直接用metl
函数处理上述的数据,会有什么结果。
aql <- melt(airquality) # [a]ir [q]uality [l]ong formathead(aql)
variable value1 ozone 412 ozone 363 ozone 124 ozone 185 ozone NA6 ozone 28
然后再看看末尾的几个数据
tail(aql)
variable value913 day 25914 day 26915 day 27916 day 28917 day 29918 day 30
默认情况下,melt
认为所有数值列的变量均有值。很多情况下,这都是我们想要的情况。在这里,我们想知道每个月(month)以及每天(day)的ozone, solar.r, wind以及temp的值。因此,我们需要告诉melt
,month和day是"ID variables"。ID variables就是那些能够区分不同行数据的变量,个人感觉类似于数据库中的主键。
aql <- melt(airquality, id.vars = c("month", "day"))head(aql)
month day variable value1 5 1 ozone 412 5 2 ozone 363 5 3 ozone 124 5 4 ozone 185 5 5 ozone NA6 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_value1 5 1 ozone 412 5 2 ozone 363 5 3 ozone 124 5 4 ozone 185 5 5 ozone NA6 5 6 ozone 28
从宽格式数据变换到长格式的数据比较直观,然后反过来则需要一些二外的功夫。
在reshape2中有好几个cast
版本的函数。若你经常使用data.frame,就需要使用dcast
函数。acast
函数返回向量、矩阵或者数组。
dcast
借助于公式来描述数据的形状,左边参数表示"ID variables",而右边的参数表示measured variables。可能需要几次尝试,才能找到合适的公式。
这里,我们需要告知dcast
,month和day是ID variables,variable则表示measured variables。
aql <- melt(airquality, id.vars = c("month", "day"))aqw <- dcast(aql, month + day ~ variable)head(aqw)
month day ozone solar.r wind temp1 5 1 41 190 7.4 672 5 2 36 118 8.0 723 5 3 12 149 12.6 744 5 4 18 313 11.5 625 5 5 NA NA 14.3 566 5 6 28 NA 14.9 66
head(airquality) # original data
ozone solar.r wind temp month day1 41 190 7.4 67 5 12 36 118 8.0 72 5 23 12 149 12.6 74 5 34 18 313 11.5 62 5 45 NA NA 14.3 56 5 56 28 NA 14.9 66 5 6
除了需要调整下列变量的顺序,我们已经恢复出原始数据。下图将有助解释所发生的情况。
![here is the dcast illustration][2]
蓝色阴影块是能够表示每一行数据的ID variables;红色阴影块包含了将待生成数据的列名;而灰色的数据表示用于填充相关区域的数据。
令人产生疑惑的情况往往是,一个数据单元有一个以上的数据。比如,我们的ID variables不包含day,
dcast(aql, month ~ variable)
month ozone solar.r wind temp1 5 31 31 31 312 6 30 30 30 303 7 31 31 31 314 8 31 31 31 315 9 30 30 30 30
同时还有以下的警告信息
Aggregation function missing: defaulting to length
再次查看dcast
的输出数据,可以看到每个单元是month与climate组合的个数。所得到数据是month对应的day的记录数。当每个单元有多个数据是,需要告诉dcast
如何聚合(aggregate
)这些数据,比如取均值(mean
),计算中位数(median
),或者简单的求和(sum
)。比如,在这里,我们简单的计算下均值,同时通过na.rm = TRUE
删除NA值。
dcast(aql, month ~ variable, fun.aggregate = mean, na.rm = TRUE)
month ozone solar.r wind temp1 5 23.61538 181.2963 11.622581 65.548392 6 29.44444 190.1667 10.266667 79.100003 7 59.11538 216.4839 8.941935 83.903234 8 59.96154 171.8571 8.793548 83.967745 9 31.44828 167.4333 10.180000 76.90000```### 3. 参考文献本文源于[Sean C. Anderson][1]的文档,具体的可以查看 <http://seananderson.ca/2013/10/19/reshape.html>[1]: http://seananderson.ca/2013/10/19/reshape.html[2]: http://upload-images.jianshu.io/upload_images/58036-d3cdd2487970a0a5.png "what is this "
联系客服