R高效数据处理包—reshape2 长数据 vs 宽数据

R高效数据处理包—reshape2 长数据 vs 宽数据

在本篇文章,我们将展示如何使用reshape2包将宽型数据转换成长型数据,反之亦然。这个包也是由Hadley Wickham开发和维护的。

升级包 tidyr:https://www.omicsclass.com/article/1475

长数据 vs 宽数据

对于宽型数据,每列代表一个不同的变量。例如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包中两个主要的函数是:

  1. melt——将宽型数据融合成长型数据
  2. cast——将长型数据转成宽型数据

melt

接下来,我们在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函数的作用是将长型数据转成宽型数据。cast函数的两种主要类型是:

  1. dcast——返回的结果是一个数据框
  2. acast——返回的结果可以是向量、矩阵或者数组

由于数据框对象是最常见的,我将演示如何使用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列里存在非数值型数据,否则会得到错误。

  • 发表于 2019-02-27 20:36
  • 阅读 ( 4715 )
  • 分类:R

0 条评论

请先 登录 后评论
omicsgene
omicsgene

生物信息

702 篇文章

作家榜 »

  1. omicsgene 702 文章
  2. 安生水 350 文章
  3. Daitoue 167 文章
  4. 生物女学霸 120 文章
  5. xun 82 文章
  6. 红橙子 78 文章
  7. rzx 76 文章
  8. CORNERSTONE 72 文章