2016-02-12 36 views

回答

4

我们可以从data.table尝试rbindlist。将数据集放置在list,rbind中,其中第一列为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为对象名称,因为它是更容易输入。

+0

请问这仍然工作,如果dataframes有不同colnames? – zx8754

+0

@ zx8754是的,'rbindlist'对此起作用。 – akrun

+1

这很有用,谢谢。 – zx8754

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的方法相比,要特别注意最后三行。


在基础R的等价物,去年 “data.table” 的做法是这样的:

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”)

1

你也可以用rbind为此在基础R,而无需使用额外的软件包,但你必须设置的df2的COLUMNNAMES一样的COLUMNNAMES:

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