合并多个连接的列
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_5
和 mean_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.default
到 data.frame
的 list
,然后 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")
我有两个不同的列用于几个样本,它们是相连的。我想将类型 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_5
和 mean_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.default
到 data.frame
的 list
,然后 unlist
每个 list
元素遍历 list
并转换为 data.frame
data.frame(lapply(split.default(df1, sub("\d+", "", names(df1))),
unlist, use.names = FALSE))
使用 reshape
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
andmean_vel_1
, ...mean_vel_5
in a new data frame, with allabs_dist
in one column and allmean_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")