pivot_longer: 基于列名作为输入的模式
pivot_longer: pattern based on column names as input
我有一个包含以下模式列的宽数据框:a1_var1
、a2_var1
、a3_var1
、a1_var2
、a2_var2
、a3_var2
,等等。我想将其转向更长的时间,创建一个名为 a
的新变量,其中包含“a”后面的数字值(1、2、3)以及 [= 的所有值21=] 包含在列 var1
中(对于 var2
也是如此)。
考虑这个示例数据:
df <- data.frame(`id` = seq(1:3),
a1_var1 = c(111, 211, 311),
a2_var1 = c(121, 221, 321),
a3_var1 = c(131, 231, 331),
a1_var2 = c(112, 212, 312),
a2_var2 = c(122, 222, 322),
a3_var2 = c(132, 232, 332)) # first number is ID, second number is "a[x]" value, third number is var[x]
我现在想将数据转换为具有以下列的长格式:id
(每行不再唯一),a
(包含从中获取变量的数字,例如 a1_var2
:a
= 1
),var1
(包含来自 ax_var1
列的所有值,即 x11
、x21
、 x31
) 和 var2
(包含来自 ax_var2
列的所有值,即 x12
、x22
、x32
)。
我想实现如下结构:
id a var1 var2
1 1 111 112
1 2 121 122
1 3 131 132
2 1 211 212
2 2 221 222
2 3 231 232
3 1 311 312
3 2 321 322
3 3 331 332
到目前为止,我正在对每个 varx
进行硬编码,如下所示:
df %>% select(-c(ends_with("var2"))) %>%
pivot_longer(cols = c("a1_var1", "a2_var1", "a3_var1"), names_to = "a", values_to = "var1") %>%
mutate(a=str_extract(a, "a\d"),
a=str_extract(a, "\d"))
但是由于我有很多 varx 列,这有点麻烦 - 有人可以指出实现上述结果的更好方法吗?
我们可以在 pivot_longer
本身中执行此操作 - 即指定 names_to
为 c("a", ".value")
,其中 'a' 将是列中前缀子字符串的列名reshapeed 和 .value
表示列值。在 names_pattern
中,捕获列名的子字符串,即 'a' 之后的数字 (\d+
) 和 _
之后的第二个捕获组
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = -id, names_to = c("a", ".value"),
names_pattern = "a(\d+)_(.*)")
-输出
# A tibble: 9 × 4
id a var1 var2
<int> <chr> <dbl> <dbl>
1 1 1 111 112
2 1 2 121 122
3 1 3 131 132
4 2 1 211 212
5 2 2 221 222
6 2 3 231 232
7 3 1 311 312
8 3 2 321 322
9 3 3 331 332
我有一个包含以下模式列的宽数据框:a1_var1
、a2_var1
、a3_var1
、a1_var2
、a2_var2
、a3_var2
,等等。我想将其转向更长的时间,创建一个名为 a
的新变量,其中包含“a”后面的数字值(1、2、3)以及 [= 的所有值21=] 包含在列 var1
中(对于 var2
也是如此)。
考虑这个示例数据:
df <- data.frame(`id` = seq(1:3),
a1_var1 = c(111, 211, 311),
a2_var1 = c(121, 221, 321),
a3_var1 = c(131, 231, 331),
a1_var2 = c(112, 212, 312),
a2_var2 = c(122, 222, 322),
a3_var2 = c(132, 232, 332)) # first number is ID, second number is "a[x]" value, third number is var[x]
我现在想将数据转换为具有以下列的长格式:id
(每行不再唯一),a
(包含从中获取变量的数字,例如 a1_var2
:a
= 1
),var1
(包含来自 ax_var1
列的所有值,即 x11
、x21
、 x31
) 和 var2
(包含来自 ax_var2
列的所有值,即 x12
、x22
、x32
)。
我想实现如下结构:
id a var1 var2
1 1 111 112
1 2 121 122
1 3 131 132
2 1 211 212
2 2 221 222
2 3 231 232
3 1 311 312
3 2 321 322
3 3 331 332
到目前为止,我正在对每个 varx
进行硬编码,如下所示:
df %>% select(-c(ends_with("var2"))) %>%
pivot_longer(cols = c("a1_var1", "a2_var1", "a3_var1"), names_to = "a", values_to = "var1") %>%
mutate(a=str_extract(a, "a\d"),
a=str_extract(a, "\d"))
但是由于我有很多 varx 列,这有点麻烦 - 有人可以指出实现上述结果的更好方法吗?
我们可以在 pivot_longer
本身中执行此操作 - 即指定 names_to
为 c("a", ".value")
,其中 'a' 将是列中前缀子字符串的列名reshapeed 和 .value
表示列值。在 names_pattern
中,捕获列名的子字符串,即 'a' 之后的数字 (\d+
) 和 _
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = -id, names_to = c("a", ".value"),
names_pattern = "a(\d+)_(.*)")
-输出
# A tibble: 9 × 4
id a var1 var2
<int> <chr> <dbl> <dbl>
1 1 1 111 112
2 1 2 121 122
3 1 3 131 132
4 2 1 211 212
5 2 2 221 222
6 2 3 231 232
7 3 1 311 312
8 3 2 321 322
9 3 3 331 332