具有多个 (x,y) 对的数据框的高格式

Tall format of data frame with multiple (x,y) pairs

我有一个数据框(实际上我更喜欢 data.table),其中包含多对 (x,y) 坐标和相应值 alpha 的列,如下所示:

    > data.frame(x_1 = 1:5, y_1 = 6:10, 
                 x_2 = 11:15, y_2 = 16:20, 
                 x_3 = 21:25, y_3=26:30, 
                 alpha = seq(0.2,1,0.2))
      x_1 y_1 x_2 y_2 x_3 y_3 alpha
    1   1   6  11  16  21  26   0.2
    2   2   7  12  17  22  27   0.4
    3   3   8  13  18  23  28   0.6
    4   4   9  14  19  24  29   0.8
    5   5  10  15  20  25  30   1.0

我需要将它组织成一个长格式,这样就有一个 x 和一个 y 列,其中来自 df 的一行坐标堆叠成三对在彼此之上; alpha 的列,每个配对都重复;对应pair索引的一列,如下:

    x  y alpha index
1   1  6   0.2     1
2  11 16   0.2     2
3  21 26   0.2     3
4   2  7   0.4     1
5  12 17   0.4     2
6  22 27   0.4     3
7   3  8   0.6     1
8  13 18   0.6     2
9  23 28   0.6     3
10  4  9   0.8     1
11 14 19   0.8     2
12 24 29   0.8     3
13  5 10   1.0     1
14 15 20   1.0     2
15 25 30   1.0     3

我曾尝试使用 gather 但没有取得多大成功 - 试图按对列融化然后复制 alpha 值让我很伤心。然后,我在 df 的行中求助于 for 循环,在每次迭代中编译值 xyalpha 的(预分配)向量,但即使对于预分配,与 python.

中的类似操作相比,这是非常慢的

在实践中,我有大约 20,000-40,000 行,更多“常量”列,如 alpha 和 3-5 对索引。

抱歉,如果有类似的问题 - 我找不到一个关于非常具体的数据操作的措辞问题。非常感谢任何帮助!

这是否按预期工作?

df %>%
  pivot_longer(cols = -alpha, names_to = c("col", "index"), names_sep = "_") %>%
  pivot_wider(names_from = col, values_from = value)

输出

# A tibble: 15 x 4
   alpha index     x     y
   <dbl> <chr> <int> <int>
 1   0.2 1         1     6
 2   0.2 2        11    16
 3   0.2 3        21    26
 4   0.4 1         2     7
 5   0.4 2        12    17
 6   0.4 3        22    27
 7   0.6 1         3     8
 8   0.6 2        13    18
 9   0.6 3        23    28
10   0.8 1         4     9
11   0.8 2        14    19
12   0.8 3        24    29
13   1   1         5    10
14   1   2        15    20
15   1   3        25    30

gather 已被 pivot_longer 取代。我认为这可以满足您的需求。

df %>% 
  pivot_longer(
    c(starts_with("x"), starts_with("y")),
    names_pattern="(.)_(.)",
    names_to=c(".value", "index")
  )
# A tibble: 15 x 4
   alpha index     x     y
   <dbl> <chr> <int> <int>
 1   0.2 1         1     6
 2   0.2 2        11    16
 3   0.2 3        21    26
 4   0.4 1         2     7
 5   0.4 2        12    17
 6   0.4 3        22    27
 7   0.6 1         3     8
 8   0.6 2        13    18
 9   0.6 3        23    28
10   0.8 1         4     9
11   0.8 2        14    19
12   0.8 3        24    29
13   1   1         5    10
14   1   2        15    20
15   1   3        25    30

这是另一种pivot_longer方法:

  1. pivot_longer 没有 alpha 只有列以 x
  2. 开头
  3. 使用window函数lead
  4. 使用 filter
  5. 删除每隔一行
  6. 创建index
library(dplyr)
library(tidyr)
df %>% 
  pivot_longer(c(-alpha, starts_with("x")),
               names_to = "names.x",
               values_to = "x"
               ) %>% 
  mutate(y = lead(x)) %>% 
  filter(row_number() %% 2 != 0) %>%  ## Delete even-rows
  select(-names.x) %>% 
  mutate(index = rep(1:3, length.out = n()))
 alpha     x     y index
   <dbl> <int> <int> <int>
 1   0.2     1     6     1
 2   0.2    11    16     2
 3   0.2    21    26     3
 4   0.4     2     7     1
 5   0.4    12    17     2
 6   0.4    22    27     3
 7   0.6     3     8     1
 8   0.6    13    18     2
 9   0.6    23    28     3
10   0.8     4     9     1
11   0.8    14    19     2
12   0.8    24    29     3
13   1       5    10     1
14   1      15    20     2
15   1      25    30     3