个性化阅读
专注于IT技术分析

R中的数据:长格式和宽格式

本文概述

本文带你了解为什么要将数据从长格式转换为宽格式,反之亦然,并探索如何使用melt()和dcast()在R中实现这一点

有时候人们需要将长格式的数据(你称其为”长格式”, 以后会清楚说明)转换为宽格式, 反之亦然。现实生活中的数据有各种各样的格式, 但是大多数R函数都是为一种特定形式设计的。

例如, 对于长格式, 将设计用于混合线性建模的lme4 :: lmer(), 用于可视化的ggplot2 :: ggplot()。但是还有其他针对宽格式设计的函数, 例如mosaicplot()。这意味着你需要转换表格以进行分析或可视化, 除非已经处理过数据且格式正确。

R中有几种用于格式转换的选项, 但是当你刚入门时, 它会变得非常混乱。

本教程将向你展示如何理解在长格式和宽格式之间转换数据的机制。你将探索以下主题:

  • 你将了解有关长格式的更多信息。
  • 然后, 你将了解广泛的形式。
  • 你将回顾长格式和宽格式之间的差异;
  • 之后, 你将看到从一种形式转换到另一种形式需要采取的步骤。
  • 最后, 你将在R的帮助下实现所有这些功能。你将学习如何使用melt()和dcast()函数将长格式转换为宽格式。

数据

Table 01
名称 性别 年2011 年2012 年2013 年2014 年2015
杰克逊·史密斯 中号 74.69 84.99 91.73 105.11 111.04
索菲亚·约翰逊(Sophia Johnson) F NA NA NA NA 75.89
艾玛·威廉姆斯(Emma Williams) F NA NA 75.74 86.50 91.50
艾登·琼斯(Aiden Jones) 中号 NA NA NA 71.89 81.42
利亚姆·布朗 中号 88.24 96.91 101.85 108.13 112.45
卢卡斯·戴维斯(Lucas Davis) 中号 70.60 83.78 94.17 100.03 106.35
奥利维亚·米勒(Olivia Miller) F 64.78 80.76 87.30 97.13 103.80
艾娃·威尔逊(Ava Wilson) F 88.77 96.45 104.72 112.84 NA

该表显示了一个小地方的婴儿身高。身高是从2011年到2015年的测量值。你可能已经知道, NA表示”不可用”。从NA的位置, 你可以算出婴儿的年龄, 但婴儿的确切年龄却不高可从表中获得。这张表看起来井井有条, 但是对于任何想研究婴儿成长的人来说, 都有一个问题:重要的信息不是测量婴儿的绝对时间, 而是测量婴儿的年龄。你可以将此信息插入表格吗?在下面, 你可以看到一种方法:

Table 02
名称 性别 年龄0 1岁 AGE2岁 3岁 4岁 5岁 6岁
杰克逊·史密斯 中号 NA 76.69 84.91 97.06 105.73 107.32 NA
索菲亚·约翰逊(Sophia Johnson) F NA 76.05 NA NA NA NA NA
艾玛·威廉姆斯(Emma Williams) F 72.65 82.46 91.76 NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 69.76 79.89 NA NA NA NA NA
利亚姆·布朗 中号 NA NA 85.34 93.22 105.78 105.84 114.82
卢卡斯·戴维斯(Lucas Davis) 中号 71.59 84.87 92.10 100.73 104.21 NA NA
奥利维亚·米勒(Olivia Miller) F 62.74 81.39 92.02 98.32 106.44 NA NA
艾娃·威尔逊(Ava Wilson) F NA NA 88.39 100.67 107.58 111.52 NA

NA的数量有所增加。 ##宽格式数据但是, 如果你想传达一个婴儿多少个月的时间, 该怎么办?就像这样:

Table 03
名称 性别 m4 m6 m7 10米 m12 m55 m60 m65 m72
杰克逊·史密斯 中号 NA NA NA NA 76.69 NA 107.32 NA NA
索菲亚·约翰逊(Sophia Johnson) F NA NA NA NA 76.05 NA NA NA NA
艾玛·威廉姆斯(Emma Williams) F NA NA NA 72.65 NA NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 NA 69.76 NA NA NA NA NA NA NA
利亚姆·布朗 中号 NA NA NA NA NA NA 105.84 NA 114.82
卢卡斯·戴维斯(Lucas Davis) 中号 NA NA 71.59 NA NA 104.21 NA NA NA
奥利维亚·米勒(Olivia Miller) F 62.74 NA NA NA NA NA NA NA NA
艾娃·威尔逊(Ava Wilson) F NA NA NA NA NA NA NA 111.52 NA

上表中有大量的NA。如果婴儿的相对测量时间不同, 那么宽的形式会浪费很多空间。另一种选择是包括2015年的婴儿年龄, 但这只有在绝对测量时间都相同的情况下才可能。如果婴儿的测量时间相差数月, 而你想知道以月为单位的年龄, 则该方法无效。那么这个例子似乎是唯一的方法。在这种情况下, 你可以考虑使用长格式。 ##长格式数据一位婴儿的所有测量结果均以宽格式显示在一行中, 而你只会看到一位婴儿的所有测量值以长格式显示。获取后者的最简单方法是在一行中显示孩子的名字, 测量时间和测量值(身高)。这正是该表显示的内容:

Table 04
名称 性别 高度
奥利维亚·米勒(Olivia Miller) F 4 62.74
艾登·琼斯(Aiden Jones) 中号 6 69.76
卢卡斯·戴维斯(Lucas Davis) 中号 7 71.59
艾玛·威廉姆斯(Emma Williams) F 10 72.65
杰克逊·史密斯 中号 12 76.69
利亚姆·布朗 中号 72 114.82

如果按名称对数据进行排序, 则会得到类似下表所示的内容。显然, 该表比上面的表3占用的空间要小!

Table 05
名称 性别 高度
杰克逊·史密斯 中号 12 76.69
杰克逊·史密斯 中号 24 84.91
杰克逊·史密斯 中号 36 97.06
杰克逊·史密斯 中号 48 105.73
杰克逊·史密斯 中号 60 107.32
索菲亚·约翰逊(Sophia Johnson) F 12 76.05
艾玛·威廉姆斯(Emma Williams) F 10 72.65
艾娃·威尔逊(Ava Wilson) F 65 111.52

长与宽

再次注意宽格式和长格式之间的根本区别:一个简单的区别是, 宽格式在一行中显示了一个人的许多测量结果, 而列名显示了这些测量结果。

下表连续显示了利亚姆·布朗(Liam Brown)在2011-2015年的身高:

Table 06
名称 性别 年2011 年2012 年2013 年2014 年2015
利亚姆·布朗 中号 88.24 96.91 101.85 108.13 112.45

在长形Liam Brown的身高中, 一栏显示:

Table 07
名称 性别 +
利亚姆·布朗 中号 85.34
利亚姆·布朗 中号 93.22
利亚姆·布朗 中号 105.78
利亚姆·布朗 中号 105.84
利亚姆·布朗 中号 114.82

如你所见, 你不知道什么是测量值。如果记下列名称, 则看起来像这样:

Table 08
名称 性别 年2011, 2012, 2013, 2014, 2015
利亚姆·布朗 中号 85.34
利亚姆·布朗 中号 93.22
利亚姆·布朗 中号 105.78
利亚姆·布朗 中号 105.84
利亚姆·布朗 中号 114.82

但是, 这有它自己的问题。索菲亚·约翰逊(Sophia Johnson)的身高未在2011-2014年进行测量。因此, 如你在下面看到的, 无法轻松设置列名:

Table 09
名称 性别 ?
利亚姆·布朗 中号 85.34
利亚姆·布朗 中号 93.22
利亚姆·布朗 中号 105.78
利亚姆·布朗 中号 105.84
利亚姆·布朗 中号 114.82
索菲亚·约翰逊(Sophia Johnson) F 76.05

从宽格式到长格式

可以将宽格式转换为长格式是逐步的过程。在将一行中的度量转换为一列之前, 你可以使表的制作方式使其每行中仅包含一个度量。让我们对此表进行操作:

Table 10
名称 性别 年龄0 1岁 AGE2岁 3岁 4岁 5岁 6岁
艾玛·威廉姆斯(Emma Williams) F 72.65 82.46 91.76 NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 69.76 79.89 NA NA NA NA NA

结果如下表所示:

Table 11
名称 性别 年龄0 1岁 AGE2岁 3岁 4岁 5岁 6岁
艾玛·威廉姆斯(Emma Williams) F 72.65 NA NA NA NA
艾玛·威廉姆斯(Emma Williams) F 82.46 NA
艾玛·威廉姆斯(Emma Williams) F 91.76
艾登·琼斯(Aiden Jones) 中号 69.76 NA NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 79.89

在将分散在各列中的度量收集到一列之前, 你需要再创建一列以说明度量是什么, 如下所示:

Table 12
名称 性别 测量 年龄0 1岁 AGE2岁 3岁 4岁 5岁 6岁
艾玛·威廉姆斯(Emma Williams) F 年龄0 72.65 NA NA NA NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46 NA
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76 NA NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 1岁 79.89

列名称通常是”度量”或”键”。你可以在上表中注意到, 列名和一列中分别有” age0″, ” age1″, ” age2″, ” age3″, ” age4″, ” age5″。如果省略列名, 则表如下所示。

Table 13
名称 性别 测量 + __ ___ ____ _____ ______ _______
艾玛·威廉姆斯(Emma Williams) F 年龄0 72.65 NA NA NA NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76 NA NA NA NA NA
艾登·琼斯(Aiden Jones) 中号 1岁 79.89

由于每一行只有一个度量, 因此你可以将它们收集到一列中, 结果将如下所示:

Table 14
名称 性别 测量
艾玛·威廉姆斯(Emma Williams) F 年龄0 72.65
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89

让我们为所有度量创建新的列名称。通常, 它被命名为”值”:

Table 15
名称 性别 测量
艾玛·威廉姆斯(Emma Williams) F 年龄0 72.65
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89

让我们看看上表。你是否注意到”年龄”在重复?你可以省略重复的实体, 这将为你提供以下结果:

Table 16
名称 性别 年龄
艾玛·威廉姆斯(Emma Williams) F 0 72.65
艾玛·威廉姆斯(Emma Williams) F 1 82.46
艾玛·威廉姆斯(Emma Williams) F 2 91.76
艾登·琼斯(Aiden Jones) 中号 0 69.76
艾登·琼斯(Aiden Jones) 中号 1 79.89

在每一行中重复的年龄现在是列名。上表中的列名值可以更具体。你将其替换为高度, 这更具有启发性。你可以在下表中看到结果:

Table 17
名称 性别 年龄 高度
艾玛·威廉姆斯(Emma Williams) F 0 72.65
艾玛·威廉姆斯(Emma Williams) F 1 82.46
艾玛·威廉姆斯(Emma Williams) F 2 91.76
艾登·琼斯(Aiden Jones) 中号 0 69.76
艾登·琼斯(Aiden Jones) 中号 1 79.89

让我们将表15与表17进行比较。值(表15的列名称之一)可以表示任何含义, 但是表17的高度具有非常特殊的含义:它只能指定高度, 而表15中的值可以是任何值, 例如身高, 体重, 速度或颜色。另一种方式如下所示:

Table 18
名称 性别 测量
艾玛·威廉姆斯(Emma Williams) F 身高 72.65
艾玛·威廉姆斯(Emma Williams) F 身高 82.46
艾玛·威廉姆斯(Emma Williams) F 身高 91.76
艾登·琼斯(Aiden Jones) 中号 身高 69.76
艾登·琼斯(Aiden Jones) 中号 身高 79.89

让我们考虑一下其中的度量是多种多样的情况。如果测量的是身高, 体重和体重指数, 则如下表所示。但是在这种情况下, 列值具有不同比例的数值, 因此读取它们可能会造成混淆。在此表中, 身高以厘米为单位, 体重以千克为单位:

Table 19
名称 性别 测量
艾玛·威廉姆斯(Emma Williams) F 高度 72.65
艾玛·威廉姆斯(Emma Williams) F 重量 8.22
艾玛·威廉姆斯(Emma Williams) F 体重指数 22.60
艾登·琼斯(Aiden Jones) 中号 高度 69.76
艾登·琼斯(Aiden Jones) 中号 重量 8.51

因此, 在将宽格式转换为长格式时, 需要确定将哪些值收集到一列中。之后, 你可以确定列名称。

让我们总结一下到目前为止所讲的内容:要将width- from从long转换为long-form, 需要确定要修改的列是否位于一列中。这样做时, 许多列被合并为一列。因此, 你需要该列的列名, 你可以在下表中看到它:

Table 20
id1 id2 年龄0 1岁 AGE2岁
艾玛·威廉姆斯(Emma Williams) F NA 82.46 91.76
艾登·琼斯(Aiden Jones) 中号 69.76 79.89 NA
艾玛·威廉姆斯(Emma Williams) F NA 82.46 91.76
Table 21
id1 id2 年龄0 1岁 AGE2岁
艾玛·威廉姆斯(Emma Williams) F NA
艾玛·威廉姆斯(Emma Williams) F 82.46
艾玛·威廉姆斯(Emma Williams) F 91.76
艾登·琼斯(Aiden Jones) 中号 69.76
艾登·琼斯(Aiden Jones) 中号 79.89
艾登·琼斯(Aiden Jones) 中号 NA
艾玛·威廉姆斯(Emma Williams) F NA
艾玛·威廉姆斯(Emma Williams) F 82.46
艾玛·威廉姆斯(Emma Williams) F 91.76
Table 22
id1 id2 年龄_ 年龄0 1岁 AGE2岁
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89
艾登·琼斯(Aiden Jones) 中号 AGE2岁 NA
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
Table 23
id1 id2 年龄_
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89
艾登·琼斯(Aiden Jones) 中号 AGE2岁 NA
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
Table 24
id1 id2
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89
艾登·琼斯(Aiden Jones) 中号 AGE2岁 NA
艾玛·威廉姆斯(Emma Williams) F 年龄0 NA
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
Table 25
id1 id2
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76
艾登·琼斯(Aiden Jones) 中号 年龄0 69.76
艾登·琼斯(Aiden Jones) 中号 1岁 79.89
艾玛·威廉姆斯(Emma Williams) F 1岁 82.46
艾玛·威廉姆斯(Emma Williams) F AGE2岁 91.76

让我们看一下上表中的ID1和ID2列。 id2没有指定个人, 但它是个人的属性(性别)。换句话说, 你可以说这是一个度量。因此, 你可以将其转换为较长格式。最长格式由三列组成, 分别是id, key和value。

Table 26
id
艾玛·威廉姆斯(Emma Williams) 性别 F
艾玛·威廉姆斯(Emma Williams) 1岁 82.46
艾玛·威廉姆斯(Emma Williams) AGE2岁 91.76
艾登·琼斯(Aiden Jones) 性别 F
艾登·琼斯(Aiden Jones) 年龄0 69.76
艾登·琼斯(Aiden Jones) 1岁 79.89
艾玛·威廉姆斯(Emma Williams) 性别 F
艾玛·威廉姆斯(Emma Williams) 1岁 82.46
艾玛·威廉姆斯(Emma Williams) AGE2岁 91.76

上表显示了表25中最长的格式。但是不同的人可以使用相同的名字。

在这种情况下, 长格式可能会造成混淆, 因为id不能指定一个人。你可以在名称后面加上数字以区分人员(例如, 使用R函数make.unique()), 但是你无法将更改后的名称与原始名称与数字区分开。想想一个真正的名字叫” John.2″的人!

解决此问题的明显方法是为其他人分配不同的号码ID。在这种情况下, 名称是另一个度量。

下表显示, 即使名称也被视为度量。从某种意义上说, 这是真正的最长格式。

Table 27
id
1 名称 艾玛·威廉姆斯(Emma Williams)
1 性别 F
1 1岁 82.46
1 AGE2岁 91.76
2 名称 艾登·琼斯(Aiden Jones)
2 性别 F
2 年龄0 69.76
2 1岁 79.89
3 名称 艾玛·威廉姆斯(Emma Williams)
3 性别 F
3 1岁 82.46
3 AGE2岁 91.76

最长的形式是制作宽格式的最简单形式。如果将表20至表25中所示的将宽格式转换为长格式的过程反向进行, 则可以进入宽格式。下表显示了此过程:

Table 28. Measurements in key column are repeated on the column name
id 名称 性别 年龄0 1岁 AGE2岁
1 名称 艾玛·威廉姆斯(Emma Williams)
1 性别 F
1 1岁 82.46
1 AGE2岁 91.76
2 名称 艾登·琼斯(Aiden Jones)
2 性别 F
2 年龄0 69.76
2 1岁 79.89
3 名称 艾玛·威廉姆斯(Emma Williams)
3 性别 F
3 1岁 82.46
3 AGE2岁 91.76
Table 29. key column can be erased
id 名称 性别 年龄0 1岁 AGE2岁
1 艾玛·威廉姆斯(Emma Williams)
1 F
1 82.46
1 91.76
2 艾登·琼斯(Aiden Jones)
2 F
2 69.76
2 79.89
3 艾玛·威廉姆斯(Emma Williams)
3 F
3 82.46
3 91.76
Table 30. The same id can be gathered into one row
id 名称 性别 年龄0 1岁 AGE2岁
1 艾玛·威廉姆斯(Emma Williams) F 82.46 91.76
1
1
1
2 艾登·琼斯(Aiden Jones) F 69.76 79.89
2
2
2
3 艾玛·威廉姆斯(Emma Williams) F 82.46 91.76
3
3
3
Table 31. Delete any row that has no measurements
id 名称 性别 年龄0 1岁 AGE2岁
1 艾玛·威廉姆斯(Emma Williams) F 82.46 91.76
2 艾登·琼斯(Aiden Jones) F 69.76 79.89
3 艾玛·威廉姆斯(Emma Williams) F 82.46 91.76

将宽格式转换为长格式的关键因素是决定将哪些列收集为一列。

但这不必只是一栏。如有必要, 你可以使用两列, 如下表所示:

Table 32
名称 性别 h2011 h2012 w2011 w2012
杰克逊·史密斯 中号 74.69 84.99 9.60 12.0
奥利维亚·米勒(Olivia Miller) F NA 80.76 7.15 10.7
艾娃·威尔逊(Ava Wilson) F 88.77 96.45 NA 15.0

你能把它做成长形吗?

h2011, h2012, w2011, w2012列是2011年和2012年的平均身高和体重。身高和体重的测量单位为厘米, 公斤。因此, 高度和重量都只能使用一列, 也可以在此表中使用两列:

Table 33
名称 性别 高度 重量
杰克逊·史密斯 中号 2011 74.69 9.60
杰克逊·史密斯 中号 2012 84.99 12.00
奥利维亚·米勒(Olivia Miller) F 2011 NA 80.76
奥利维亚·米勒(Olivia Miller) F 2012 7.15 10.70
艾娃·威尔逊(Ava Wilson) F 2011 88.77 96.45
艾娃·威尔逊(Ava Wilson) F 2012 NA 15.00

这是长格式还是宽格式?

从R中的长数据到宽数据

让我们用R进行长形和宽形之间的覆盖。有许多功能和软件包可用于此任务。

Table 34
功能 to_long_form to_wide_form
堆放/堆放 实用程序 拆箱
重塑 统计资料 重塑(direction =” long”, …) 重塑(direction =” wide”, …)
熔铸 重塑2 熔化 广播
收集/传播 tidyr 收集 传播

在这里, 我将解释如何使用reshape2包的melt()和dcast()函数。原因是stack()和unstack()是基本函数, 因此需要对它们的结果进行后处理。请注意, gather()和spread()是tidyr函数, 它们也非常流行, 但本教程将不介绍它们。

你可能可以使用的另一个功能是stats包随附的reshape()。实际上, 不要为此功能感到困惑, 因为还有一个名为reshape的软件包!该软件包与reshape2一起为那些为reshape()苦苦挣扎的人而开发。另外, 函数reshape()似乎假设数据是纵向的, 这意味着测量会随时间重复。

让我们将表35中的数据转换为长格式。假设下表存储了一个名为dat的data.frame。

Table 35
名称 性别 年2011 年2012 年2013
杰克逊·史密斯 中号 74.69 84.99 91.73
艾玛·威廉姆斯(Emma Williams) F NA NA 75.74
利亚姆·布朗 中号 88.24 NA 101.85
艾娃·威尔逊(Ava Wilson) F 88.77 96.45 NA

婴儿= data.frame(name = c(” Jackson Smith”, ” Emma Williams”, ” Liam Brown”, ” Ava Wilson”), 性别= c(” M”, ” F”, ” M”, ” F” ), year2011 = c(74.69, NA, 88.24, 88.77), year2012 = c(84.99, NA, NA, 96.45), year2013 = c(91.73, 75.74, 101.83, NA))婴儿

##            name gender year2011 year2012 year2013
## 1 Jackson Smith      M    74.69    84.99    91.73
## 2 Emma Williams      F       NA       NA    75.74
## 3    Liam Brown      M    88.24       NA   101.83
## 4    Ava Wilson      F    88.77    96.45       NA

你要问的问题是:”哪些列合并为一个列?”。

分别是2011年, 2012年和2013年。当你使用函数melt()时, 应为measure.vars列出这些列:

melt(babies, measure.vars = c("year2011", "year2012", "year2013"))

##             name gender variable  value
## 1  Jackson Smith      M year2011  74.69
## 2  Emma Williams      F year2011     NA
## 3     Liam Brown      M year2011  88.24
## 4     Ava Wilson      F year2011  88.77
## 5  Jackson Smith      M year2012  84.99
## 6  Emma Williams      F year2012     NA
## 7     Liam Brown      M year2012     NA
## 8     Ava Wilson      F year2012  96.45
## 9  Jackson Smith      M year2013  91.73
## 10 Emma Williams      F year2013  75.74
## 11    Liam Brown      M year2013 101.83
## 12    Ava Wilson      F year2013     NA

year2011, year2012, year2013是位于第3、4、5th的列, 因此你可以使用:

melt(babies, measure.vars = 3:5)

##             name gender variable  value
## 1  Jackson Smith      M year2011  74.69
## 2  Emma Williams      F year2011     NA
## 3     Liam Brown      M year2011  88.24
## 4     Ava Wilson      F year2011  88.77
## 5  Jackson Smith      M year2012  84.99
## 6  Emma Williams      F year2012     NA
## 7     Liam Brown      M year2012     NA
## 8     Ava Wilson      F year2012  96.45
## 9  Jackson Smith      M year2013  91.73
## 10 Emma Williams      F year2013  75.74
## 11    Liam Brown      M year2013 101.83
## 12    Ava Wilson      F year2013     NA

结果在上表中。注意列名变量和值。表23和表24显示需要新的列名。函数melt()具有新列的默认名称-变量和值。你可以使用variable.name =和value.name =争论覆盖默认值。让我们在下面做这个:

melt(babies, measure.vars=3:5, variable.name="year", value.name="height")

##             name gender     year height
## 1  Jackson Smith      M year2011  74.69
## 2  Emma Williams      F year2011     NA
## 3     Liam Brown      M year2011  88.24
## 4     Ava Wilson      F year2011  88.77
## 5  Jackson Smith      M year2012  84.99
## 6  Emma Williams      F year2012     NA
## 7     Liam Brown      M year2012     NA
## 8     Ava Wilson      F year2012  96.45
## 9  Jackson Smith      M year2013  91.73
## 10 Emma Williams      F year2013  75.74
## 11    Liam Brown      M year2013 101.83
## 12    Ava Wilson      F year2013     NA

在上面的示例中指定了测量值。对于你要处理的那些设置, Id可以间接指定测量值。因此, 你可以选择ID列而不是度量。

两者的结果相同。第一个选择ID的列, 第二个选择要收集的列:

melt(babies, id.vars=c("name", "gender"))

melt(babies, measure.vars = c("year2011", "year2012", "year2013"))

##             name gender variable  value
## 1  Jackson Smith      M year2011  74.69
## 2  Emma Williams      F year2011     NA
## 3     Liam Brown      M year2011  88.24
## 4     Ava Wilson      F year2011  88.77
## 5  Jackson Smith      M year2012  84.99
## 6  Emma Williams      F year2012     NA
## 7     Liam Brown      M year2012     NA
## 8     Ava Wilson      F year2012  96.45
## 9  Jackson Smith      M year2013  91.73
## 10 Emma Williams      F year2013  75.74
## 11    Liam Brown      M year2013 101.83
## 12    Ava Wilson      F year2013     NA

如果你同时指定id.vars和measure.vars, 则其中任何未包含的列将从结果中排除。例如, 查看下面的代码块:

melt(babies, id.vars=c("name"), measure.vars=c("year2011", "year2012"))

##            name variable value
## 1 Jackson Smith year2011 74.69
## 2 Emma Williams year2011    NA
## 3    Liam Brown year2011 88.24
## 4    Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 6 Emma Williams year2012    NA
## 7    Liam Brown year2012    NA
## 8    Ava Wilson year2012 96.45

另外, na.rm = T可以消除NA:

melt(babies, id.vars=c("name"), measure.vars=c("year2011", "year2012"), na.rm=T)

##            name variable value
## 1 Jackson Smith year2011 74.69
## 3    Liam Brown year2011 88.24
## 4    Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 8    Ava Wilson year2012 96.45

dcast()函数执行与melt()相反的操作。 id, variable和value是最长格式的列。 dcast(data, id〜variable, value.var =” value”)将最长格式转换为宽格式。

babiesLong <- melt(babies, id.vars=c("name"), measure.vars=c("year2011", "year2012"), na.rm=T)
babiesLong

##            name variable value
## 1 Jackson Smith year2011 74.69
## 3    Liam Brown year2011 88.24
## 4    Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 8    Ava Wilson year2012 96.45

babiesLong的名称是id, 变量是变量, 值是值。因此, 你可以使用dcast()将其转换为长格式:

dcast(babiesLong, name ~ variable, value.var="value")

##            name year2011 year2012
## 1    Ava Wilson    88.77    96.45
## 2 Jackson Smith    74.69    84.99
## 3    Liam Brown    88.24       NA

总结

似乎就是这样。在本教程中, 你专注于理解重塑数据的逻辑和过程。通常, 长格式是首选分析方法, 但也有执行方法。适当时, 宽格式的数据呈现可以节省空间, 但是随着缺失值数量的增加, 你最好转换为长格式。

对于格式转换, 你需要专注于度量值。长格式的座右铭是每行一次测量, 而宽格式的一行则有很多测量。当你对收集在一列中的所有列进行测量时, 原始列名需要保留在另一列中。当你在分散到整个列的一列中进行测量时, 你需要从可变列中找出列名称。

一旦了解了该过程, 就可以轻松使用dcast()和melt()之类的功能!

赞(2)
未经允许不得转载:srcmini » R中的数据:长格式和宽格式

评论 抢沙发

评论前必须登录!