以特殊方式获取长格式
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_longer
从 tidyr
:
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
.value
在 pivot_longer
中有特殊含义,这意味着长格式的新列的名称将来自原始列名称。这些名称是如何派生的是使用 names_pattern
参数定义的。在 names_pattern
中我们提到从名称中提取所有字符 ([A-Za-z]+
) 作为新名称。所以N1
、N2
变成了N
,它们合并成一列。 E1
、E2
和 Class1
、Class2
对也是如此。
我有一个相当宽格式的数据集,我希望它是长格式的。通常我在这种情况下使用 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_longer
从 tidyr
:
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
.value
在 pivot_longer
中有特殊含义,这意味着长格式的新列的名称将来自原始列名称。这些名称是如何派生的是使用 names_pattern
参数定义的。在 names_pattern
中我们提到从名称中提取所有字符 ([A-Za-z]+
) 作为新名称。所以N1
、N2
变成了N
,它们合并成一列。 E1
、E2
和 Class1
、Class2
对也是如此。