合并多个连接的列

Merging multiple connected columns

我有两个不同的列用于几个样本,它们是相连的。我想将类型 1 的所有列合并为一列,所有类型 2 的列合并为一列,但行应保持连接。

示例:

a1 <- c(1, 2, 3, 4, 5)
b1 <- c(1, 4, 9, 16, 25)
a2 <- c(2, 4, 6, 8, 10)  
b2 <- c(4, 8, 12, 16, 20)
df1 <- data.frame(a1, b1, a2, b2)

  a1  b1  a2  b2
1 1   1   2   4
2 2   4   4   8
3 3   9   6   12
4 4   16  8   16
5 5   25  10  20

我想要这样:

   a  b 
1  1  1
2  2  4
3  2  4
4  3  9
5  4  8
6  4  16
7  5  25
8  6  12
9  8  16
10 10 20

My case

这是我的例子。我有很多名称不同的列,我想在新数据框中提取 abs_dist_1, ... abs_dist_5mean_vel_1, ... mean_vel_5,所有 abs_dist 在一列中,所有 mean_vel 在一列中列,但仍处于连接状态。

我试过 unlist,但当然连接断开了。

提前致谢。

通过将 names_sep 指定为正则表达式环视以在小写字母 ([a-z]) 和列名

library(dplyr)
library(tidyr)
df1 %>%
   pivot_longer(cols = everything(), names_to = c( '.value', 'grp'), 
       names_sep = "(?<=[a-z])(?=[0-9])") %>%
   select(-grp)

-输出

# A tibble: 10 x 2
#       a     b
#   <dbl> <dbl>
# 1     1     1
# 2     2     4
# 3     2     4
# 4     4     8
# 5     3     9
# 6     6    12
# 7     4    16
# 8     8    16
# 9     5    25
#10    10    20

对于编辑后的 ​​post,我们需要更改 names_sep 即分隔符现在 _ 在小写字母和数字之间

df1 %>%
   pivot_longer(cols = everything(), names_to = c( '.value', 'grp'), 
       names_sep = "(?<=[a-z])_(?=[0-9])") %>%
   select(-grp)

或与 base R 一起,在列名的子字符串上使用 split.defaultdata.framelist,然后 unlist 每个 list 元素遍历 list 并转换为 data.frame

data.frame(lapply(split.default(df1, sub("\d+", "", names(df1))), 
       unlist, use.names = FALSE))

使用 reshape

的基础 R 选项
subset(
  reshape(
    setNames(df1, gsub("(\d)", ".\1", names(df1))),
    direction = "long",
    varying = 1:ncol(df1)
  ),
  select = -c(time, id)
)

给予

     a  b
1.1  1  1
2.1  2  4
3.1  3  9
4.1  4 16
5.1  5 25
1.2  2  4
2.2  4  8
3.2  6 12
4.2  8 16
5.2 10 20

为了完整起见,这里有一个解决方案,它使用 data.table::melt()patterns() 函数来指定属于一起的列:

library(data.table)
melt(setDT(df1), measure.vars = patterns(a = "a", b = "b"))[
  order(a,b), !"variable"]
     a  b
 1:  1  1
 2:  2  4
 3:  2  4
 4:  3  9
 5:  4  8
 6:  4 16
 7:  5 25
 8:  6 12
 9:  8 16
10: 10 20

这再现了 OP 示例数据集的预期结果。

一个更现实的例子:仅重塑选定的列

随着问题的编辑,OP 澄清了生产数据包含的列比需要重塑的列多得多

I have a lot of columns with different names and I want to extract abs_dist_1, ... abs_dist_5 and mean_vel_1, ... mean_vel_5 in a new data frame, with all abs_dist in one column and all mean_vel in one column, but still connected.

因此,OP 希望一次性提取和重塑感兴趣的列,同时忽略数据集中的所有其他数据。

为了模拟这种情况,我们需要一个更详细的数据集,其中还包括其他列:

df2 <- cbind(df1, c1 = 11:15, c2 = 21:25)
df2
   a1 b1 a2 b2 c1 c2
1  1  1  2  4 11 21
2  2  4  4  8 12 22
3  3  9  6 12 13 23
4  4 16  8 16 14 24
5  5 25 10 20 15 25

上面代码的修改版本

library(data.table)
cols <- c("a", "b")
result <- melt(setDT(df2), measure.vars = patterns(cols), value.name = cols)[, ..cols]
setorderv(result, cols)
result

我们得到

     a  b
 1:  1  1
 2:  2  4
 3:  3  9
 4:  4 16
 5:  5 25
 6:  2  4
 7:  4  8
 8:  6 12
 9:  8 16
10: 10 20

对于编辑中所示的生产数据集,OP 需要设置

cols <- c("abs_dist", "mean_vel")