在本篇文章,我们将展示如何使用reshape2包将宽型数据转换成长型数据,反之亦然。这个包也是由Hadley Wickham开发和维护的。
升级包 tidyr:https://www.omicsclass.com/article/1475
对于宽型数据,每列代表一个不同的变量。例如datasets包中的mtcars数据集就是宽型数据:
# Wide format mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 Valiant 18.1 6 225 105 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
长型数据可以包含两个以上的列,尤其是提供ID变量的时候。如下所述。
在实际应用中,宽型数据更具可读性,长型数据则更适合做分析。因此,知道如何在它们之间进行转换非常有用。
reshape2包中两个主要的函数是:
接下来,我们在datasets包中的mtcars数据集上进行操作。它一开始是上面展示的宽型数据。我们要把它融合成下面的长型数据:
mtcars$car <- rownames(mtcars) mtcarsMelt <- melt(mtcars) head(mtcarsMelt) car variable value 1 Mazda RX4 mpg 21.0 2 Mazda RX4 Wag mpg 21.0 3 Datsun 710 mpg 22.8 4 Hornet 4 Drive mpg 21.4 5 Hornet Sportabout mpg 18.7 6 Valiant mpg 18.1
注:译者在R里得到的是melt自动选取car作为ID变量,原文是选取car和cyl作为ID变量。要得到相同结果只需在参数id.vars中指定相应变量即可。
我们可以通过参数variable.name和value.name分别对variable和value列重命名。例如,我们想对所有的汽车根据它的汽缸数和齿轮数做分类。可以像下面这样:
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组合值却是相同的,这不是好的办法。当你需要把数据转回宽型数据时会有点问题了(下面会看到)。
cast函数的作用是将长型数据转成宽型数据。cast函数的两种主要类型是:
由于数据框对象是最常见的,我将演示如何使用dcast。下面展示的是长型数据转回成宽型数据:
mtcarsMelt <- melt(mtcars) mtcarsCast <- dcast(mtcarsMelt, car ~ variable) head(mtcarsCast) car mpg cyl disp hp drat wt qsec vs am gear carb 1 AMC Javelin 15.2 8 304 150 3.15 3.435 17.30 0 0 3 2 2 Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3 4 3 Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3 4 4 Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3 4 5 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 6 Dodge Challenger 15.5 8 318 150 2.76 3.520 16.87 0 0 3 2
dcast函数通过一个式子来把数据转成宽型数据。在本篇译文中,由于我在R上自动的到ID变量只有car,所以我给出的式子是car ~ variable。这里car是ID变量,variable变量列的名称。要想跟原文一样只需在melt时指定id.vars参数即可。
如果我们指定cyl和gear作为ID变量融合数据后,再转回宽型变量时,会得到如下所示的结果:
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
会得到警告信息:Aggregation function 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列。这是因为我们不希望在mtcarsMelt的value列里存在非数值型数据,否则会得到错误。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!