以特殊方式获取长格式

Get long format in a special way

我有一个相当宽格式的数据集,我希望它是长格式的。通常我在这种情况下使用 melt 但在这里我不知道这是否有效。那是我的数据集:

> Data <-
+   data.table(
+     ID = 1:6,
+     N1 = round(rnorm(6)),
+     E1 = round(rnorm(6)),
+     N2 = round(rnorm(6, 5)),
+     E2 = round(rnorm(6, 5)),
+     Class1 = 1,
+     Class2 = 2
+   )
> 
> Data
   ID N1 E1 N2 E2 Class1 Class2
1:  1  0  0  4  5      1      2
2:  2 -1  0  5  5      1      2
3:  3  0 -1  5  5      1      2
4:  4  1  0  5  5      1      2
5:  5 -1 -1  4  7      1      2
6:  6 -2 -1  6  6      1      2

我想要的数据集是那个:

> Data.Long <- 
+   rbind(
+     Data[, .(ID, N = N1, E = E1, Class = Class1)],
+     Data[, .(ID, N = N2, E = E2, Class = Class2)]
+   )
> Data.Long
    ID  N  E Class
 1:  1  0  0     1
 2:  2 -1  0     1
 3:  3  0 -1     1
 4:  4  1  0     1
 5:  5 -1 -1     1
 6:  6 -2 -1     1
 7:  1  4  5     2
 8:  2  5  5     2
 9:  3  5  5     2
10:  4  5  5     2
11:  5  4  7     2
12:  6  6  6     2

对于这种情况,我对 rbind 和变量选择的尝试非常好。但是在我的真实数据集中,我有更多的变量,比如 ID,而且我可能有两个以上的 类。你能想到一个更好的代码,即使有很多也不会重复类?

我们可以使用 pivot_longertidyr :

tidyr::pivot_longer(Data, 
                    cols = -ID,
                    names_to = '.value',
                    names_pattern = '([A-Za-z]+)') 

#      ID     N     E Class
#   <int> <dbl> <dbl> <dbl>
# 1     1     0     0     1
# 2     1     5     6     2
# 3     2    -1    -2     1
# 4     2     6     6     2
# 5     3     2     0     1
# 6     3     6     5     2
# 7     4     0     0     1
# 8     4     4     6     2
# 9     5    -2     1     1
#10     5     5     6     2
#11     6    -1     0     1
#12     6     6     5     2

.valuepivot_longer 中有特殊含义,这意味着长格式的新列的名称将来自原始列名称。这些名称是如何派生的是使用 names_pattern 参数定义的。在 names_pattern 中我们提到从名称中提取所有字符 ([A-Za-z]+) 作为新名称。所以N1N2变成了N,它们合并成一列。 E1E2Class1Class2 对也是如此。