在 R 中重组纵向数据时如何创建新的分组变量?

How do you create new grouping variables when restructuring longitudinal data in R?

我一直在阅读 R 中 reshape2 包和其他包的文档,以将数据从宽格式重组为长格式,反之亦然。但是,我一直坚持这个问题,因为我需要为时间创建一个新变量并按时间对我的激素测量值进行分组。我以前在 SPSS 中做过这个,尽管我正在切换到 R 出于明显的原因,就像许多其他人一样。我知道在 R 中肯定有一个简单的方法可以做到这一点,但我无法弄清楚这一点。

该项目的数据来自一项纵向临床研究,其中在每个患者的 5 个不同时间点测量了 20 种不同的激素(示例虚构数据如下 - a1 是访视时的激素 'a' 1,a2 是访问 2 时的激素 'a',依此类推)。研究中共有 20 名患者,每个患者在电子表格 (id) 中都有唯一的标识符。激素数据(激素 'a'、激素 'b' 等)在我的电子表格中以宽格式排列如下:

> id     a1     a2     a3     a4     a5    b1     b2     b3     b4     b5...
>  1     21     50     28     19     15    24     90     40     35     20...
>  2     23     45     15     22     20    25     45     34     31     22...
>  3     29     88     33     32     21    78     32     33     45     21...
...

当我之前在 SPSS 中执行此操作时,软件会提示我输入 id 变量以及变量名称以将纵向测量值折叠到其中。我会创建一个名为 "visit" 的新变量,它是从 1 到 5,对应于我对每种激素进行的 5 次测量。当我在 SPSS 中这样做时,它会创建一个长格式的新输出,如下所示:

> id     visit      a     b
> 1          1     21    24
> 1          2     50    90
> 1          3     28    40
> 1          4     19    35
> 1          5     15    20
> 2          1     23    25
> 2          2     45    45
> 2          3     15    34
> 2          4     22    31
> 2          5     20    22
> 3          1     29    78
...

我试过使用 reshape,该函数似乎有效,但当我查看实际数据时,数字在宽格式和长格式之间混淆了。我一定是犯了一些非常基本的错误,但我很难弄清楚。

d_long <- reshape(d, varying = c("a1", "a2", "a3", "a4", "a5", 
    "b1", "b2", "b3", "b4", "b5"), v.names = c("a", "b"), 
    idvar = "id", times = c(1:5), direction = "long")

我认为你应该使用 reshape() 函数并使用参数 timevar 指定新的时间变量。

这可以通过 data.table 的开发版本中的 melt 轻松完成。安装开发版的说明是here.

我们将 'data.frame' 转换为 'data.table' (setDT(df1))。然后,我们在 meltmeasure 参数中指定 patterns 来匹配多个 measure 列。

library(data.table)
dM <- melt(setDT(df1), measure=patterns(c('^a\d+', '^b\d+')),
          value.name=c('a', 'b'), variable.name='visit')[order(id)]
dM
#    id visit  a  b
# 1:  1     1 21 24
# 2:  1     2 50 90
# 3:  1     3 28 40
# 4:  1     4 19 35
# 5:  1     5 15 20
# 6:  2     1 23 25
# 7:  2     2 45 45
# 8:  2     3 15 34
# 9:  2     4 22 31
#10:  2     5 20 22
#11:  3     1 29 78
#12:  3     2 88 32
#13:  3     3 33 33
#14:  3     4 32 45
#15:  3     5 21 21

数据

df1 <- structure(list(id = 1:3, a1 = c(21L, 23L, 29L), a2 = c(50L, 45L, 
88L), a3 = c(28L, 15L, 33L), a4 = c(19L, 22L, 32L), a5 = c(15L, 
20L, 21L), b1 = c(24L, 25L, 78L), b2 = c(90L, 45L, 32L), b3 = c(40L, 
34L, 33L), b4 = c(35L, 31L, 45L), b5 = c(20L, 22L, 21L)), .Names = c("id", 
"a1", "a2", "a3", "a4", "a5", "b1", "b2", "b3", "b4", "b5"),
class = "data.frame", row.names = c(NA, -3L))

这里是关于在长格式和宽格式之间转换数据的一个很好的总结。

Use R and SAS to reshape the data format: long to wide and wide to long

使用基础 R 重塑:

res <- reshape(df1, direction = "long", varying = list(2:6, 7:11), idvar = "id",
               v.names = c("a", "b"), timevar = "visit")
res[order(res$id),]

给出:

    id visit  a  b
1.1  1     1 21 24
1.2  1     2 50 90
1.3  1     3 28 40
1.4  1     4 19 35
1.5  1     5 15 20
2.1  2     1 23 25
2.2  2     2 45 45
2.3  2     3 15 34
2.4  2     4 22 31
2.5  2     5 20 22
3.1  3     1 29 78
3.2  3     2 88 32
3.3  3     3 33 33
3.4  3     4 32 45
3.5  3     5 21 21