合并两个数据帧以按顺序获取每个数据帧的备用行

时间:2016-02-12 07:26:14

标签: r merge

我的data.frame DATA

  k    l   g
1 A 2004  12
2 B 2004 3.4
3 C 2004 4.5

另一个data.frame DATA2

  i    d   t
1 A 2012  22
2 B 2012 4.8
3 C 2012 5.6

我想要

1 A 2004  12
1 A 2012  22
2 B 2004 3.4
2 B 2012 4.8
3 C 2004 4.5
3 C 2012 5.6

3 个答案:

答案 0 :(得分:4)

我们可以从rbindlist尝试data.table。将数据集放在listrbind,第一列包含rbindlistorder

library(data.table)
rbindlist(list(df1, df2))[order(k)]
#   k    l    g
#1: A 2004 12.0
#2: A 2012 22.0
#3: B 2004  3.4
#4: B 2012  4.8
#5: C 2004  4.5
#6: C 2012  5.6

或使用dplyr

library(dplyr)
bind_rows(df1, setNames(df2, names(df1))) %>% 
           arrange(k)

注意:我使用df1df2代替DATADATA2作为对象名称,因为它更容易输入。

答案 1 :(得分:3)

您可以尝试“gdata”包中的interleave功能。但是,这将要求您的输入具有相同的列名并具有相同的行数。

方法是:

library(gdata)      # for interleave
do.call(interleave, lapply(list(df1, df2), setNames, paste0("V", 1:ncol(df1))))
#    V1   V2   V3
# 1   A 2004 12.0
# 11  A 2012 22.0
# 2   B 2004  3.4
# 21  B 2012  4.8
# 3   C 2004  4.5
# 31  C 2012  5.6

或者,正如我的评论@ akrun所说,根据第一列是否是分组变量,你可能想稍微修改他的方法。

例如,假设有第三个data.frame,其行数与其他行不同。 interleave不适用于此,但rbindlist方法会。

df3 <- do.call(rbind, lapply(list(df1, df2), setNames, c("A", "B", "Z")))

rbindlist(list(df1, df2, df3), idcol = TRUE)[, N := sequence(.N), by = .id][order(N)]
#     .id k    l    g N
#  1:   1 A 2004 12.0 1
#  2:   2 A 2012 22.0 1
#  3:   3 A 2004 12.0 1
#  4:   1 B 2004  3.4 2
#  5:   2 B 2012  4.8 2
#  6:   3 B 2004  3.4 2
#  7:   1 C 2004  4.5 3
#  8:   2 C 2012  5.6 3
#  9:   3 C 2004  4.5 3
# 10:   3 A 2012 22.0 4
# 11:   3 B 2012  4.8 5
# 12:   3 C 2012  5.6 6

与@ akrun的方法相比,要特别注意最后三行。

最后一个“data.table”方法的基数R中的等价物将类似于:

x <- do.call(rbind, lapply(c("df1", "df2", "df3"), function(x) {
  setNames(cbind(rn = x, get(x)), c("id", paste0("V", 1:ncol(get(x)))))
}))
x[order(ave(as.numeric(x$id), x$id, FUN = seq_along)), ]

(所以道德是,使用“data.table”。)

答案 2 :(得分:1)

您也可以在基座R中使用rbind执行此操作,而无需使用额外的套餐,但您必须将df2的列名设置为与df1中的列名相同:

colnames(df2) <- colnames(df1) # or: setNames(df2, colnames(df1))
new.df <- rbind(df1,df2)
new.df <- new.df[order(new.df$k),]

这将产生以下数据帧:

> new.df
   k    l    g
1  A 2004 12.0
11 A 2012 22.0
2  B 2004  3.4
21 B 2012  4.8
3  C 2004  4.5
31 C 2012  5.6