R - 基于一列合并两个数据帧,而不重复行并保留更多数据



我的目标是根据列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

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

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)或许多其他方式一样获得rowid。

我想更详细地阐述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

最新更新