R语言 合并两个数据框,使每个数据框按顺序交替排列

sg2wtvxw  于 2023-01-22  发布在  其他
关注(0)|答案(4)|浏览(245)

我的 Dataframe DATA

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

另一个 Dataframe DATA2

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

我想得到

c0vxltue

c0vxltue1#

我们可以从data.table尝试rbindlist。将数据集放在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作为对象名称,因为这样更容易键入。

guicsvcw

guicsvcw2#

你可以尝试使用“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,其行数与其他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”。)*
jk9hmnmh

jk9hmnmh3#

你也可以在带有rbind的base R中这样做,而不需要使用额外的包,但是你必须将df2的列名设置为与df1中的列名相同:

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

这将产生以下 Dataframe :

> 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
23c0lvtd

23c0lvtd4#

使用dplyr的解决方案,不需要键列,也不修改原始顺序(如果 Dataframe 没有按"id"列排序)。

library(dplyr)

stopifnot((N <- nrow(DATA)) == nrow(DATA2))

INTER_DATA <- setNames(DATA2, names(DATA)) %>%
    bind_rows(DATA, .) %>%
    arrange(rep(seq_len(N), length = n()))

结果:

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

相关问题