概念定义
翻看网络上诸多有关进行数据库横纵向转换、或长宽转换的博文,发现大家对于“横向”与“纵向”的数据库的定义并不完全相同,经过学习与摸索,所幸达到了我原本期望的效果。因此将过程与一些简单的思路记录下来。
且由于数据库管理的水平有限,本笔记中所定义的数据框的“横向”、“纵向”以及“键值对”格式,皆为了方便操作而来,不见得严谨。
"横向"结构
如上图所示,向量order1表示观察样本的序号,在该数据框中,针对每个样本应当有三个变量:实际住院天数、编码、诊断,其中编码与诊断至多观察了4次。
在我所期望的理想的横向数据框中,一条观察记录必然只对应一个样本,意味着向量order1的取值是不能够存在重复值的。针对同一个样本的多项观察应当被写作多条向量、并入数据框中。
“纵向”结构
如图,针对样本的观察、仅依照观察角度的不同记录为各个向量,一个向量代表着一个观察角度。比如图中,针对order1中给出的样本,一共只有实际住院天数、编码、诊断三个角度、因此除order1本身外,有且仅有这三个向量。而同一角度的多次观察、则体现为样本相同(order1取值相同)的多条记录。
“键值对”结构
如图,其与我所定义的“纵向”结构数据框最大的区别在于:针对同一个样本的其中两项观察角度——即编码与诊断,本身不再作为两个不同的向量,而是将“观察角度差异”这一概念本身作为一个向量varname1,其取值有二曰“编码、诊断”;而每个样本的每次观察到的编码与诊断的值、则统一压缩到另一个向量value1中。前者为“键”(key)、后者为“值”(value),是为“键值对”。
“纵向”转“横向”
由于工作需要,进行了数据框从“纵向”转“横向”的工作。有趣的是,“键值对”结构在这一过程中充当了“中间状态”。或许是我才疏学浅、未能找到更简便的方法。其过程大致分为两个部分,第一部分从纵向转为键值对、第二部分从键值对转为横向。
首先加载R包
library(tidyverse)
“纵向”转“键值对”
非常简单地用gather()函数
其基本的参数为:
gather(数据框, “键”的向量名, “值”的向量名, -顺势保留的向量1, -顺势保留的向量2…)
- 注意顺势保留的向量,书写向量名前方需要有一个“-”符号。
以上方数据框为例,将其命名为data1后。
data2 <- gather(data1, varname1, value1, -order1, -实际住院天数)
View(data2)
得到如下所示“键值对”结构的数据框。可以看到“编码”与“诊断”不再是向量名、而变成了“键向量”的取值。
注意,此时的“键值对”结构数据框尚不能用来直接转换为“横向”结构,否则会报错
Error: Each row of output must be identified by a unique combination of keys.
Keys are shared for …
其原因在于:由于对部分样本存在着多条观察记录的情况,比如71号样本有4次观察记录,但每次记录中观察的“编码”与“诊断”都是命名为这两个取值,也就导致了程序实际上并不能区分71号的这4个“编码”之间的区别,因此在转为横向的时候无法判断其先后顺序、或是否有顺序。
“键值对”转“横向”
因此需要将该“键值对”格式的数据框转换为如上图所示,为“键向量”的取值赋予一定的顺序。该步骤的转换我是通过excel进行操作的,十分简便、此不赘述。
此时再通过spread()函数进行拆分,将之转换为“横向”结构
其基本参数为:
spread(数据框, 键向量名称, 值向量名称)
spread(data1, varname1, value1)
即可以得到如图所示的“横向”结构数据框
至于横向格式向纵向格式的转换,若将来有工作涉及到再行补录入本笔记。