我有三个数据,每个数据都包含一列和相同的行,但所有五个数据中的顺序不同,我想根据第一列合并五个数据。
column1
X 7
B 5
Y 2
D 1
Z 0
column2
D 7
Z 5
X 2
y 6
B 7
column3
y 4
D 4
Z 8
B 7
x 2
我想要的结果是这样的
column1 column2 column3
x 7 2 2
B 5 7 7
Y 2 6 4
D 1 7 4
Z 0 5 8
这可以通过
merge
功能轻松完成。
df1 <- data.frame(rows = c("A", "B", "C", "D", "E"), column1 = c(7, 5, 2, 1, 0))
df2 <- data.frame(rows = c("D", "E", "A", "C", "B"), column2 = c(7, 5, 2, 6, 7))
df3 <- data.frame(rows = c("C", "D", "E", "B", "A"), column3 = c(4, 4, 8, 7, 2))
result <- merge(df1, df2, by = "rows", all = TRUE)
result <- merge(result, df3, by = "rows", all = TRUE)
print(result)
这应该能满足你的需求。
rows column1 column2 column3
1 A 7 2 2
2 B 5 7 7
3 C 2 6 4
4 D 1 7 4
5 E 0 5 8
使用
tidyverse
:
library(tidyverse)
list(df1, df2, df3)%>%
map(rownames_to_column) %>%
reduce(full_join, 'rowname') %>%
column_to_rownames()
column1 column2 column3
A 7 2 2
B 5 7 7
C 2 6 4
D 1 7 4
E 0 5 8
在基础R中,您可以使用以下方法:
Reduce(merge, lapply(df_list, \(x)
cbind(x, xx = row.names(x)))) |> _[-1]
# column1 column2 column3
# 1 7 2 2
# 2 5 7 7
# 3 2 6 4
# 4 1 7 4
# 5 0 5 8
另一种方法是按行名称重新排序,然后将它们放在一起。将它们组合在列表中,然后使用
do.call
将所有内容重新组合在一起时,这样做会更容易。我还将其包装在 setNames
中,将列重命名为所需的列名称:
df_list <- list(df1, df2, df3)
setNames(do.call(data.frame, lapply(df_list, \(x) x[order(rownames(x)),])),
paste0("column", 1:3))
# column1 column2 column3
# 1 7 2 2
# 2 5 7 7
# 3 2 6 4
# 4 1 7 4
# 5 0 5 8
上面的操作与手动操作相同,虽然速度较慢,但可能更容易解释发生的情况:
df1 <- df1[order(rownames(df1)),]
df2 <- df2[order(rownames(df2)),]
df3 <- df3[order(rownames(df3)),]
data.frame(column1 = df1, column2 = df2, column3 = df3)
# column1 column2 column3
# 1 7 2 2
# 2 5 7 7
# 3 2 6 4
# 4 1 7 4
# 5 0 5 8
数据:
df1 <- read.table(text = "column1
A 7
B 5
C 2
D 1
E 0", h = TRUE)
df2 <- read.table(text = "column2
D 7
E 5
A 2
C 6
B 7", h = TRUE)
df3 <- read.table(text = "column3
C 4
D 4
E 8
B 7
A 2", h = TRUE)