我有多个文件,包含许多行和三列,需要在前两列匹配的基础上合并它们。文件1
12 13 a
13 15 b
14 17 c
4 9 d
. . .
. . .
81 23 h
文件2
12 13 e
3 10 b
14 17 c
4 9 j
. . .
. . .
1 2 k
档案3
12 13 m
13 15 k
1 7 x
24 9 d
. . .
. . .
1 2 h
等等。 我想合并它们以获得以下结果
12 13 a e m
13 15 b k
14 17 c c
4 9 d j
3 10 b
24 9 d
. . .
. . .
81 23 h
1 2 k
1 7 x
答案 0 :(得分:1)
对于这些类型的问题,通常会想到的第一件事是merge
,可能与Reduce(function(x, y) merge(x, y, by = "somecols", all = TRUE), yourListOfDataFrames)
一起使用。
然而,merge
并不总是最有效的功能,特别是因为它看起来像你想要"崩溃"从左到右填充行的所有值,这不是默认的merge
行为。
相反,我建议您将所有内容堆叠成一个长data.frame
并在添加索引变量后重新整形。
以下是两种方法:
mget
将您的所有data.frame
放入list
。 rbind_all
将list
转换为单个data.frame
。sequence(n())
中的mutate
来自" dplyr"分组数据并创建索引。 spread
转变为长期"格式为"宽"格式。library(dplyr)
library(tidyr)
combined <- rbind_all(mget(ls(pattern = "^file\\d")))
combined %>%
group_by(V1, V2) %>%
mutate(time = sequence(n())) %>%
ungroup() %>%
spread(time, V3, fill = "")
# Source: local data frame [7 x 5]
#
# V1 V2 1 2 3
# 1 1 7 x
# 2 3 10 b
# 3 4 9 d j
# 4 12 13 a e m
# 5 13 15 b k
# 6 14 17 c c
# 7 24 9 d
mget
将您的所有data.frame
放入list
。rbindlist
将该列表转换为单个data.table
。sequence(.N)
按群组生成序列。dcast.data.table
转换&#34; long&#34; data.table
进入广泛的&#34;之一。library(data.table)
dcast.data.table(
rbindlist(mget(ls(pattern = "^file\\d")))[,
time := sequence(.N), by = list(V1, V2)],
V1 + V2 ~ time, value.var = "V3", fill = "")
# V1 V2 1 2 3
# 1: 1 7 x
# 2: 3 10 b
# 3: 4 9 d j
# 4: 12 13 a e m
# 5: 13 15 b k
# 6: 14 17 c c
# 7: 24 9 d
这两个答案都假设我们从以下示例数据开始:
file1 <- structure(
list(V1 = c(12L, 13L, 14L, 4L), V2 = c(13L, 15L, 17L, 9L),
V3 = c("a", "b", "c", "d")), .Names = c("V1", "V2", "V3"),
class = "data.frame", row.names = c(NA, -4L))
file2 <- structure(
list(V1 = c(12L, 3L, 14L, 4L), V2 = c(13L, 10L, 17L, 9L),
V3 = c("e", "b", "c", "j")), .Names = c("V1", "V2", "V3"),
class = "data.frame", row.names = c(NA, -4L))
file3 <- structure(
list(V1 = c(12L, 13L, 1L, 24L), V2 = c(13L, 15L, 7L, 9L),
V3 = c("m", "k", "x", "d")), .Names = c("V1", "V2", "V3"),
class = "data.frame", row.names = c(NA, -4L))