如何使用data.table优化嵌套for循环?

时间:2014-06-10 16:12:28

标签: r for-loop data.table apply

我有兴趣使用data.table优化一些代码。我觉得我应该能够比当前的解决方案做得更好,并且它不能很好地扩展(随着行数的增加)。

考虑我有一个值矩阵,其中ID表示人,其余值是特征(在我的情况下为谱系)。我想创建一个逻辑矩阵,反映两个ID(行)是否共享其行(包括ID)中的任何值。我最近一直在使用data.table,但我无法弄清楚如何更有效地做到这一点。我已经尝试(并且失败)嵌套应用语句,或者以某种方式使用data.table的.SD函数来完成此任务。

工作代码如下。

m <- matrix(rep(1:10,2),nrow=5,byrow=T)
m[c(1,3),3:4] <- NA
dt <- data.table(m)
setnames(dt,c("id","v1","v2","v3"))
res <- matrix(data=NA,nrow=5,ncol=5)
dimnames(res) <- list(dt[,id],dt[,id])
for (i in 1:nrow(dt)){
  for (j in i:nrow(dt)){
    res[j,i] <- res[i,j] <-length(na.omit(intersect(as.numeric(dt[i]),as.numeric(dt[j])))) > 0 
  }
}
res

1 个答案:

答案 0 :(得分:1)

前一段时间我遇到过类似的问题,有人帮我解决了。这是帮助转换为你的问题......

tm<-t(m) #transpose the matrix
dtt<-data.table(tm[2:4,]) #take values of matrix into data.table
setnames(dtt,as.character(tm[1,])) #make data.table column names
comblist<-combn(names(dtt),2,FUN=list) #create list of all possible column combinations
preresults<-dtt[,lapply(comblist, function(x)     length(na.omit(intersect(as.numeric(get(x[1])),as.numeric(get(x[2]))))) > 0)] #recreate your double for loop
preresults<-melt(preresults,measure.vars=names(preresults)) #change columns to rows
preresults[,c("LHS","RHS"):=lapply(1:2,function(i)sapply(comblist,"[",i))] #add column labels
preresults[,variable:=NULL] #kill unneeded column

关于如何让我的preresults采用与res格式相同的格式,我正在填补空白,但这可以为您提供所需的性能提升。