这是在两组相互映射的字符串之间找到最佳互惠匹配的问题。
我拥有的两个data.frame
包含将第一个集映射到另一个集合(下面是df1
)和其他映射方向(df2
下面)的结果
映射获得score
。此外,每个字符串都有一个parent
,而且几个不同的字符串具有相同的parent
。
以下是模拟数据:
library(dplyr)
set.seed(1)
#generate the first string set mapping data.frame
df1 <- data.frame(query = paste("a",unlist(sapply(1:5,function(i) rep(i,ceiling(runif(1,1,3))))),sep="."),stringsAsFactors = F)
#add hits and scores
df1 <- do.call(rbind,lapply(unique(df1$query),function(q) {
dplyr::filter(df1,query == q) %>%
dplyr::mutate(hit = paste("b",sample(5,nrow(.),replace = F),sep="."),score = runif(nrow(.),0,100))
}))
#add parents
df1 <- left_join(df1,data.frame(query=unique(df1$query),parent = paste("p.a",sample(3,5,replace=T),sep="."),stringsAsFactors = F),by=c("query"="query"))
#generate the second string set mapping data.frame
df2 <- data.frame(query = paste("b",unlist(sapply(1:5,function(i) rep(i,ceiling(runif(1,1,3))))),sep="."),stringsAsFactors = F)
#add hits and scores
df2 <- do.call(rbind,lapply(unique(df2$query),function(q) {
dplyr::filter(df2,query == q) %>%
dplyr::mutate(hit = paste("a",sample(5,nrow(.),replace = F),sep="."),
score = runif(nrow(.),0,100))
}))
#add parents
df2 <- left_join(df2,data.frame(query=unique(df2$query),parent = paste("p.b",sample(3,5,replace=T),sep="."),stringsAsFactors = F),by=c("query"="query"))
我想要的是拥有一个返回以下内容的高效函数:
对于第一个集合中的每个字符串(unique(df1$query)
),如果它映射到最高score
的字符串映射回其最高score
(倒数最佳匹配)返回该匹配的ID,映射score
和匹配的parent
ID,否则返回NA
以获取匹配的ID和score
。至于父级,如果parent
是最佳互惠匹配,则返回匹配的parent
ID,否则返回NA
。
生成的data.frame
应包含以下列:
set.a.id
,set.a.parent.id
,set.b.match
,set.b.match.score
,set.b.parent.id
。
对于df1
和df2,按query
和score
排序:
df1[order(df1$query,-df1$score),]
query hit score parent
1 a.1 b.4 84.72860 p.a.1
2 a.1 b.1 57.64333 p.a.1
3 a.1 b.2 56.02473 p.a.1
5 a.2 b.3 82.18000 p.a.2
4 a.2 b.4 72.56507 p.a.2
6 a.2 b.1 59.24316 p.a.2
7 a.3 b.3 71.47014 p.a.3
8 a.3 b.4 22.60246 p.a.3
10 a.4 b.2 35.13778 p.a.2
11 a.4 b.1 26.89667 p.a.2
9 a.4 b.4 20.33758 p.a.2
12 a.5 b.2 26.85910 p.a.2
13 a.5 b.4 26.77832 p.a.2
df2[order(df2$query,-df2$score),]
query hit score parent
1 b.1 a.2 90.76623 p.b.2
2 b.1 a.5 24.57950 p.b.2
3 b.2 a.5 39.58975 p.b.1
4 b.2 a.1 39.11946 p.b.1
6 b.3 a.5 35.94917 p.b.1
5 b.3 a.4 11.57524 p.b.1
8 b.4 a.5 80.93301 p.b.2
7 b.4 a.4 57.07636 p.b.2
9 b.4 a.3 10.13098 p.b.2
11 b.5 a.5 49.70569 p.b.1
10 b.5 a.2 12.88346 p.b.1
这是结果data.frame
:
res.df <- data.frame(set.a.id = unique(df1$query),set.a.parent.id = unique(df1$parent),
set.b.match = c(NA,NA,NA,NA,"b.2"),set.b.match.score = c(NA,NA,NA,NA,26.85910),
set.b.parent.id = c(NA,"p.b.1",NA,"p.b.1","p.b.1"))