如何通过匹配 R 中所有可能的组合来将多列从宽转为长?

问题描述 投票:0回答:1

我发现了这个案例这个其他,但他们并没有完全回答我的问题。

输入数据采用宽格式:

dat0
    # A tibble: 5 × 6
         id gp       a1    a2    a3    a4
      <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
    1     1 A         2    10   150  1000
    2     2 B         4    20   200  3000
    3     3 C         7    30   350  4000
    4     4 D         8    40   400  7000
    5     5 E         9    50   700  8000  

dat0 <-
structure(list(id = c(1, 2, 3, 4, 5), gp = c("A", "B", "C", "D", 
"E"), a1 = c(2, 4, 7, 8, 9), a2 = c(10, 20, 30, 40, 50), a3 = c(150, 
200, 350, 400, 700), a4 = c(1000, 3000, 4000, 7000, 8000)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -5L)) 

如何将多列旋转为两列

ax
ay
,以便:

  • 表示初始列
    a1
    a4
    的所有组合,
  • 最初的两个列(此处为
    id
    gp
    ,作为示例)被复制尽可能多的组合,
  • 创建一个新列
    ax_vs_ay
    来对组合进行分类。

所需的输出数据:

print(dat1, n=30)
# A tibble: 30 × 5
      id gp    ax_vs_ay    ax    ay
   <dbl> <chr> <chr>    <dbl> <dbl>
 1     1 A     a1_vs_a2     2    10
 2     2 B     a1_vs_a2     4    20
 3     3 C     a1_vs_a2     7    30
 4     4 D     a1_vs_a2     8    40
 5     5 E     a1_vs_a2     9    50
 6     1 A     a1_vs_a3     2   150
 7     2 B     a1_vs_a3     4   200
 8     3 C     a1_vs_a3     7   350
 9     4 D     a1_vs_a3     8   400
10     5 E     a1_vs_a3     9   700
11     1 A     a1_vs_a4     2  1000
12     2 B     a1_vs_a4     4  3000
13     3 C     a1_vs_a4     7  4000
14     4 D     a1_vs_a4     8  7000
15     5 E     a1_vs_a4     9  8000
16     1 A     a2_vs_a3    10   150
17     2 B     a2_vs_a3    20   200
18     3 C     a2_vs_a3    30   350
19     4 D     a2_vs_a3    40   400
20     5 E     a2_vs_a3    50   700
21     1 A     a2_vs_a4    10  1000
22     2 B     a2_vs_a4    20  3000
23     3 C     a2_vs_a4    30  4000
24     4 D     a2_vs_a4    40  7000
25     5 E     a2_vs_a4    50  8000
26     1 A     a3_vs_a4   150  1000
27     2 B     a3_vs_a4   200  3000
28     3 C     a3_vs_a4   350  4000
29     4 D     a3_vs_a4   400  7000
30     5 E     a3_vs_a4   700  8000  

感谢您的帮助

r pivot combinations long-format-data
1个回答
1
投票

请原谅我不太精通

dplyr
,但我希望它能有所帮助

dat0 %>%
    pivot_longer(!c(id, gp)) %>%
    reframe(
        ax_vs_ay = combn(name, 2, paste0, collapse = "_vs_"),
        value = combn(value, 2, \(x) setNames(data.frame(t(x)), paste0("a", c("x", "y"))), simplify = FALSE), .by = c(id, gp)
    ) %>%
    unnest(value)

这给出了

# A tibble: 30 × 5
      id gp    ax_vs_ay     ax    ay
   <dbl> <chr> <chr[1d]> <dbl> <dbl>
 1     1 A     a1_vs_a2      2    10
 2     1 A     a1_vs_a3      2   150
 3     1 A     a1_vs_a4      2  1000
 4     1 A     a2_vs_a3     10   150
 5     1 A     a2_vs_a4     10  1000
 6     1 A     a3_vs_a4    150  1000
 7     2 B     a1_vs_a2      4    20
 8     2 B     a1_vs_a3      4   200
 9     2 B     a1_vs_a4      4  3000
10     2 B     a2_vs_a3     20   200
11     2 B     a2_vs_a4     20  3000
12     2 B     a3_vs_a4    200  3000
13     3 C     a1_vs_a2      7    30
14     3 C     a1_vs_a3      7   350
15     3 C     a1_vs_a4      7  4000
16     3 C     a2_vs_a3     30   350
17     3 C     a2_vs_a4     30  4000
18     3 C     a3_vs_a4    350  4000
19     4 D     a1_vs_a2      8    40
20     4 D     a1_vs_a3      8   400
21     4 D     a1_vs_a4      8  7000
22     4 D     a2_vs_a3     40   400
23     4 D     a2_vs_a4     40  7000
24     4 D     a3_vs_a4    400  7000
25     5 E     a1_vs_a2      9    50
26     5 E     a1_vs_a3      9   700
27     5 E     a1_vs_a4      9  8000
28     5 E     a2_vs_a3     50   700
29     5 E     a2_vs_a4     50  8000
30     5 E     a3_vs_a4    700  8000
© www.soinside.com 2019 - 2024. All rights reserved.