ins*_*iko 8 optimization performance r match data.table
我在R中有两个数据框,我需要逐行计算元素匹配,最后获得一个列,其中包含两个表的笛卡尔积的长度和两行的ID.此外,表格非常大,行数不同,但列数相同.
我有以下代码,但多次运行时速度很慢.
library(data.table)
table_1<-data.table(matrix(c(1:24),nrow = 4))
table_2<-data.table(matrix(c(11:34),nrow = 4))
names(table_1)<-c("s1", "s2","s3","s4","s5","s6")
names(table_2)<-c("a1","a2","a3","a4","a5","a6")
table_1$ID<-seq.int(nrow(table_1))
table_2$ID_ap<-seq.int(nrow(table_2))
setcolorder(table_1, c("ID", "s1", "s2","s3","s4","s5","s6"))
setcolorder(table_2, c("ID_ap","a1","a2","a3","a4","a5","a6"))
CJ.table<-function(X,Y) setkey(X[,c(k=1,.SD)],k)[Y[,c(k=1,.SD)],allow.cartesian=TRUE][,k:=NULL]
join<-CJ.table(table_1,table_2)
R<-subset(join, select=c("ID_ap","ID"))
R$Ac<- (join$s1 == join$a1) + (join$s1 ==join$a2) + (join$s1 ==join$a3) + (join$s1 ==join$a4) + (join$s1 ==join$a5) + (join$s1 ==join$a6)+
(join$s2 == join$a1) + (join$s2 ==join$a2) + (join$s2 ==join$a3) + (join$s2 ==join$a4) + (join$s2 ==join$a5) + (join$s2 ==join$a6)+
(join$s3 == join$a1) + (join$s3 ==join$a2) + (join$s3 ==join$a3) + (join$s3 ==join$a4) + (join$s3 ==join$a5) + (join$s3 ==join$a6)+
(join$s4 == join$a1) + (join$s4 ==join$a2) + (join$s4 ==join$a3) + (join$s4 ==join$a4) + (join$s4 ==join$a5) + (join$s4 ==join$a6)+
(join$s5 == join$a1) + (join$s5 ==join$a2) + (join$s5 ==join$a3) + (join$s5 ==join$a4) + (join$s5 ==join$a5) + (join$s5 ==join$a6)+
(join$s6 == join$a1) + (join$s6 ==join$a2) + (join$s6 ==join$a3) + (join$s6 ==join$a4) + (join$s6 ==join$a5) + (join$s6 ==join$a6)
Run Code Online (Sandbox Code Playgroud)
这使
R
ID_ap ID Ac
1: 1 1 0
2: 1 2 0
3: 1 3 4
4: 1 4 0
5: 2 1 0
6: 2 2 0
7: 2 3 0
8: 2 4 4
9: 3 1 3
10: 3 2 0
11: 3 3 0
12: 3 4 0
13: 4 1 0
14: 4 2 3
15: 4 3 0
16: 4 4 0
Run Code Online (Sandbox Code Playgroud)
以长格式放置数据,因为列顺序无关紧要:
setnames(table_2, "ID_ap", "ID")
tabs = rbind(
melt(table_1, id="ID")[, variable := NULL],
melt(table_2, id="ID")[, variable := NULL],
idcol = TRUE)
Run Code Online (Sandbox Code Playgroud)
(1) 对于每个值,确定相关对;和
(2) 对于成对,计数值:
tabs[,
if (uniqueN(.id) > 1L) CJ(ID1 = ID[.id == 1L], ID2 = ID[.id == 2L])
, by=value][,
.N
, by=.(ID1, ID2)]
ID1 ID2 N
1: 3 1 4
2: 4 2 4
3: 1 3 3
4: 2 4 3
Run Code Online (Sandbox Code Playgroud)
(ID1, ID2)
我认为所有其他组合都是零,不需要明确列举。
如果每个 table 中的值不同,如在 OP 的示例中,那么我们可以简化:
tabs[, if (.N==2L) .(ID1 = ID[1L], ID2 = ID[2L]), by=value][, .N, by=.(ID1, ID2)]
Run Code Online (Sandbox Code Playgroud)