本文概述
- 数据
- 长与宽
- 从宽格式到长格式
- 从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 SmithM74.6984.9991.73
## 2 Emma WilliamsFNANA75.74
## 3Liam BrownM88.24NA101.83
## 4Ava WilsonF88.7796.45NA
你要问的问题是:”
哪些列合并为一个列?”
。
分别是2011年, 2012年和2013年。当你使用函数melt()时, 应为measure.vars列出这些列:
melt(babies, measure.vars = c("year2011", "year2012", "year2013"))##name gender variablevalue
## 1Jackson SmithM year201174.69
## 2Emma WilliamsF year2011NA
## 3Liam BrownM year201188.24
## 4Ava WilsonF year201188.77
## 5Jackson SmithM year201284.99
## 6Emma WilliamsF year2012NA
## 7Liam BrownM year2012NA
## 8Ava WilsonF year201296.45
## 9Jackson SmithM year201391.73
## 10 Emma WilliamsF year201375.74
## 11Liam BrownM year2013 101.83
## 12Ava WilsonF year2013NA
year2011, year2012, year2013是位于第3、4、5th的列, 因此你可以使用:
melt(babies, measure.vars = 3:5)##name gender variablevalue
## 1Jackson SmithM year201174.69
## 2Emma WilliamsF year2011NA
## 3Liam BrownM year201188.24
## 4Ava WilsonF year201188.77
## 5Jackson SmithM year201284.99
## 6Emma WilliamsF year2012NA
## 7Liam BrownM year2012NA
## 8Ava WilsonF year201296.45
## 9Jackson SmithM year201391.73
## 10 Emma WilliamsF year201375.74
## 11Liam BrownM year2013 101.83
## 12Ava WilsonF year2013NA
结果在上表中。注意列名变量和值。表23和表24显示需要新的列名。函数melt()具有新列的默认名称-变量和值。你可以使用variable.name =和value.name =争论覆盖默认值。让我们在下面做这个:
melt(babies, measure.vars=3:5, variable.name="year", value.name="height")##name genderyear height
## 1Jackson SmithM year201174.69
## 2Emma WilliamsF year2011NA
## 3Liam BrownM year201188.24
## 4Ava WilsonF year201188.77
## 5Jackson SmithM year201284.99
## 6Emma WilliamsF year2012NA
## 7Liam BrownM year2012NA
## 8Ava WilsonF year201296.45
## 9Jackson SmithM year201391.73
## 10 Emma WilliamsF year201375.74
## 11Liam BrownM year2013 101.83
## 12Ava WilsonF year2013NA
在上面的示例中指定了测量值。对于你要处理的那些设置, Id可以间接指定测量值。因此, 你可以选择ID列而不是度量。
两者的结果相同。第一个选择ID的列, 第二个选择要收集的列:
melt(babies, id.vars=c("name", "gender"))melt(babies, measure.vars = c("year2011", "year2012", "year2013"))##name gender variablevalue
## 1Jackson SmithM year201174.69
## 2Emma WilliamsF year2011NA
## 3Liam BrownM year201188.24
## 4Ava WilsonF year201188.77
## 5Jackson SmithM year201284.99
## 6Emma WilliamsF year2012NA
## 7Liam BrownM year2012NA
## 8Ava WilsonF year201296.45
## 9Jackson SmithM year201391.73
## 10 Emma WilliamsF year201375.74
## 11Liam BrownM year2013 101.83
## 12Ava WilsonF year2013NA
如果你同时指定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 year2011NA
## 3Liam Brown year2011 88.24
## 4Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 6 Emma Williams year2012NA
## 7Liam Brown year2012NA
## 8Ava 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
## 3Liam Brown year2011 88.24
## 4Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 8Ava 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
## 3Liam Brown year2011 88.24
## 4Ava Wilson year2011 88.77
## 5 Jackson Smith year2012 84.99
## 8Ava Wilson year2012 96.45
babiesLong的名称是id, 变量是变量, 值是值。因此, 你可以使用dcast()将其转换为长格式:
dcast(babiesLong, name ~ variable, value.var="value")##name year2011 year2012
## 1Ava Wilson88.7796.45
## 2 Jackson Smith74.6984.99
## 3Liam Brown88.24NA
总结似乎就是这样。在本教程中, 你专注于理解重塑数据的逻辑和过程。通常, 长格式是首选分析方法, 但也有执行方法。适当时, 宽格式的数据呈现可以节省空间, 但是随着缺失值数量的增加, 你最好转换为长格式。
对于格式转换, 你需要专注于度量值。长格式的座右铭是每行一次测量, 而宽格式的一行则有很多测量。当你对收集在一列中的所有列进行测量时, 原始列名需要保留在另一列中。当你在分散到整个列的一列中进行测量时, 你需要从可变列中找出列名称。
【R中的数据(长格式和宽格式)】一旦了解了该过程, 就可以轻松使用dcast()和melt()之类的功能!
推荐阅读