【数据整理】R用reshape2包进行数据操作
在这篇文章中,我会向大家展示如何使用reshape2包把从范围较广的数据转化成长格式,反之亦然。这篇文章由Hardely Wickham编写。
长格式与宽格式
在宽格式数据中,每一列都代表一个变量。例如,在mtcars数据集中,我们可以看到与它相关的数据:
# Wide format
mpg cyl disp hp drat wt qsec vs am gear carb
MazdaRX4 21.0 6 160110 3.90 2.620 16.46 0 1 4 4
MazdaRX4 Wag 21.0 6 160110 3.90 2.875 17.02 0 1 4 4
Datsun710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet4 Drive 21.4 6 258110 3.08 3.215 19.44 1 0 3 1
HornetSportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225105 2.76 3.460 20.22 1 0 3 1
在长格式中,一列就包含了所有的变量,而另一行则是与之相关的值。长格式数据以下面的方式展现:
# Long format
variable value
1 mpg 21.0
2 mpg 21.0
3 mpg 22.8
4 mpg 21.4
5 mpg 18.7
6 mpg 18.1
...
variable value
347 carb 2
348 carb 2
349 carb 4
350 carb 6
351 carb 8
352 carb 2
长格式数据一般都是超过两列,尤其是提供了变量名的时候,之后会展现给大家。
在实际应用中,当宽格式的数据更易于阅读的时候,长格式数据则更容易分析。因此,我们有必要去了解它们俩是怎样相互转化的。
这里是reshape2包中两个主要的函数:
melt-把宽格式数据转化成长格式。
cast-把长格式数据转化成宽格式。
melt
melt函数就是用于把宽格式数据转化成长格式数据。现在我们从数据集包中调用mtcars数据集,其数据集原来的格式就是宽格式(上面已经给大家展示过了)。现在,我们就是用这个函数来得到长格式数据:
mtcars$car <- rownames(mtcars)
mtcarsMelt <- melt(mtcars)
head(mtcarsMelt)
cyl car variable value
1 6 Mazda RX4 mpg 21.0
2 6 Mazda RX4 Wag mpg 21.0
3 4 Datsun 710 mpg 22.8
4 6 Hornet 4 Drive mpg 21.4
5 8 Hornet Sportabout mpg 18.7
6 6 Valiant mpg 18.1
这里,melt函数默认地将car和cyl作为变量名。如果你想用不同的集作为变量名,你可以单独列出要作为变量名的变量。我们也可以重新对一个变量进行命名,然后变量的所在列就会使用其变量名以及相关的参数。例如,如果我们想要对cars数据集里的cylinders和gears进行分类,可按如下操作:
mtcarsMelt <- melt(mtcars, id.vars = c('cyl', 'gear'), variable.name = 'carVariable', value.name = 'carValue')
head(mtcarsMelt)
cyl gear carVariable carValue
1 6 4 mpg 21
2 6 4 mpg 21
3 4 4 mpg 22.8
4 6 3 mpg 21.4
5 8 3 mpg 18.7
6 6 3 mpg 18.1
tail(mtcarsMelt)
cyl gear carVariable carValue
315 4 5 car Porsche 914-2
316 4 5 car Lotus Europa
317 8 5 car Ford Pantera L
318 6 5 car Ferrari Dino
319 8 5 car Maserati Bora
320 4 4 car Volvo 142E
通常来说,把变量组合起来使用是一个不错的方法,它可以有针对性的确认每个数据点所对应的变量名。因此,直接以cyl和gear作为变量名并不是一个好的方法,那是因为它们的多个数据集对应的只是相同的2个变量,而这又会在你试图把原有的数据格式转化成宽格式时带来一系列的问题。
cast
cast函数用于把长格式数据转化成宽格式数据。这里有2个主要的函数:
dcast-输出时返回一个数据框。
acast-输出时返回一个向量/矩阵/数组。
由于数据框格式是最常见的一种形式,我们会展示如何使用dcast函数。那么我们可以把现有的数据格式转化成宽格式,具体如下:
mtcarsMelt <- melt(mtcars)
mtcarsCast <- dcast(mtcarsMelt, car + cyl ~ variable)
head(mtcarsCast)
car cyl mpg disp hp drat wt qsec vs am gear carb
1 AMC Javelin 8 15.2 304 150 3.15 3.435 17.30 0 0 3 2
2 Cadillac Fleetwood 8 10.4 472 205 2.93 5.250 17.98 0 0 3 4
3 Camaro Z28 8 13.3 350 245 3.73 3.840 15.41 0 0 3 4
4 Chrysler Imperial 8 14.7 440 230 3.23 5.345 17.42 0 0 3 4
5 Datsun 710 4 22.8 108 93 3.85 2.320 18.61 1 1 4 1
6 Dodge Challenger 8 15.5 318 150 2.76 3.520 16.87 0 0 3 2
dcast函数使用了一个公式把数据转化成宽格式,而这里的公式则是car+cyl~变量,而cyl和gear是变量名,而变量则是变量所在列的名字。
下面我们看一下如果用cat和gear作为变量名会发生什么情况:
mtcarsCast <- dcast(mtcarsMelt, cyl + gear ~ variable)
head(mtcarsCast)
cyl gear mpg disp hp drat wt qsec vs am carb car
1 4 3 1 1 1 1 1 1 1 1 1 1
2 4 4 8 8 8 8 8 8 8 8 8 8
3 4 5 2 2 2 2 2 2 2 2 2 2
4 6 3 2 2 2 2 2 2 2 2 2 2
5 6 4 4 4 4 4 4 4 4 4 4 4
6 6 5 1 1 1 1 1 1 1 1 1 1
我们得到了警告消息: Aggregationfunction missing: defaulting to length。数据集所展现的结果仅仅是在每个cyl和gear的组合变量名中的每个观察值的总数而言,原因就在于dcast函数并不能辨认每个数据点所对应的变量名。然而,这里还是有一些用途的。例如,我们可以通过使用fun.aggregate参数来找出每个以cyl和gear作为组合时所有变量的平均值,操作如下:
mtcars$car <- NULL
mtcarsMelt <- melt(mtcars, id.vars = c('cyl', 'gear'))
mtcarsCast <- dcast(mtcarsMelt, cyl + gear ~ variable, fun.aggregate = mean)
head(mtcarsCast)
cyl gear mpg disp hp drat wt qsec vs am carb
1 4 3 21.500 120.100 97.0 3.70 2.465000 20.0100 1.0 0.00 1.0
2 4 4 26.925 102.625 76.0 4.11 2.378125 19.6125 1.0 0.75 1.5
3 4 5 28.200 107.700 102.0 4.10 1.826500 16.8000 0.5 1.00 2.0
4 6 3 19.750 241.500 107.5 2.92 3.337500 19.8300 1.0 0.00 1.0
5 6 4 19.750 163.800 116.5 3.91 3.093750 17.6700 0.5 0.50 4.0
6 6 5 19.700 145.000 175.0 3.62 2.770000 15.5000 0.0 1.00 6.0
这里,我们除去了car这一列,原因在于我们不希望任何非参数形式的值在每个mrcarsMelt的值列中,或者在运算的过程中会出错。
如果你有什么问题,随时都欢迎你给我们留言或者关注我们的Twitter得到更多相关的信息。
原文链接:http://www.r-bloggers.com/data-manipulation-with-reshape2/
作者:何品言,热爱英语和数据科学。
严禁修改,可以转载,请注明数据人网和原文链接http://shujuren.org/index.php/Article/update/aid/144。
更多精彩内容,请点击阅读原文。
数据人网(http://shujuren.org),数据人学习、交流和分享的家园,专注于从数据中学习,努力发觉数据之洞见,积极利用数据之价值。为“让人懂数据、用数据”之使命坚持做点事情。大家可以来投稿,做分享和传播,可以给反馈。您有什么想法,请反馈给我们,谢谢。数据人网,我们共建和共享。
请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!