基于一列合并两个数据帧,而无需复制行并保留更多数据

时间:2018-10-05 18:57:33

标签: r dataframe merge

我的目标是合并基于列genus的两个大型数据框,但是具有不复制行的特殊条件(第一次尝试中未解决);并保留来自两个数据帧的更多信息(第二次尝试中未解决),请参见所需的输出:

chromdata <- read.table(text="
 genus sp
1      Acosta       Acosta_1
2    Aguilera     Aguilera_1
3      Acosta       Acosta_2
4    Aguilera     Aguilera_2
5       other              1   # EDIT: new rows    
6       other              2",header=TRUE,fill=TRUE,stringsAsFactors=FALSE)

treedata <- read.table(text="
 genus sp
1      Acosta       Acosta_3
2    Aguilera     Aguilera_3
3      Acosta       Acosta_4
4    Aguilera     Aguilera_4
5       other              3",header=TRUE,fill=TRUE,stringsAsFactors=FALSE)

#First try
merge(chromdata,treedata, by="genus", all=F)

#Second try
chromdata$sp2<-treedata$sp[match(chromdata$genus, treedata$genus)]
chromdata
     genus         sp        sp2
1   Acosta   Acosta_1   Acosta_3
2 Aguilera Aguilera_1 Aguilera_3
3   Acosta   Acosta_2   Acosta_3 #Acosta_4 missing
4 Aguilera Aguilera_2 Aguilera_3 # Aguilera_4 missing
5    other          1          3
6    other          2          3 

所需的输出:

     genus         sp        sp2
1   Acosta   Acosta_1   Acosta_3
2 Aguilera Aguilera_1 Aguilera_3
3   Acosta   Acosta_2   Acosta_4
4 Aguilera Aguilera_2 Aguilera_4
5    other          1          3 # EDIT: new rows
6    other          2          3

2 个答案:

答案 0 :(得分:1)

您可以添加另一列进行合并:

library(data.table)
merge(
  transform(chromdata, r = rowid(genus)), 
  transform(treedata, r = rowid(genus)), 
  by=c("r", "genus")
)

  r    genus       sp.x       sp.y
1 1   Acosta   Acosta_1   Acosta_3
2 1 Aguilera Aguilera_1 Aguilera_3
3 2   Acosta   Acosta_2   Acosta_4
4 2 Aguilera Aguilera_2 Aguilera_4

如果您不想加载data.table,也可以获取诸如ave(genus, genus, FUN = seq_along)many other ways之类的rowid。

答案 1 :(得分:0)

我想详细介绍data.table方法。

首先,您可以读取数据,然后将其直接转换为data.table对象:

library(data.table)

chromdata <- as.data.table(read.table(text="
 genus sp
                        1      Acosta       Acosta_1
                        2    Aguilera     Aguilera_1
                        3      Acosta       Acosta_2
                        4    Aguilera     Aguilera_2",header=TRUE,fill=TRUE,stringsAsFactors=FALSE))

treedata <- as.data.table(read.table(text="
                       genus sp
                       1      Acosta       Acosta_3
                       2    Aguilera     Aguilera_3
                       3      Acosta       Acosta_4
                       4    Aguilera     Aguilera_4",header=TRUE,fill=TRUE,stringsAsFactors=FALSE))

在那之后,您需要一个额外的列来完成所需的合并操作:

chromdata[, N := seq_len(.N), genus]
treedata[, N := seq_len(.N), genus]

这些行为您提供组内的行ID。

最后,借助data.table包,我们可以将这两个表合并到公共列上:

chromdata[treedata, on = c("genus", "N")]

最终输出:

      genus         sp N       i.sp
1:   Acosta   Acosta_1 1   Acosta_3
2: Aguilera Aguilera_1 1 Aguilera_3
3:   Acosta   Acosta_2 2   Acosta_4
4: Aguilera Aguilera_2 2 Aguilera_4