This is edited to use native data.table()
features - hopefully it should perform better!
# make the cor matrix into an expand.grid equivalent - all combos - using CJ for cross join
cor_list<-data.table(CJ(LETTERS[1:nrow(M)],LETTERS[1:nrow(M)]))
# fill with the values for M
cor_list[,cor:=unlist(as.list(M))]
# index on combination of correlation inputs
setkey(cor_list, V1, V2)
# lookup correlation for all combos of DT v DT
DTX<-DT[,cor_list[J(Key1,DT[,Key1],DT[,Key2])],by=c("Key1","Key2")]
# index on Key2
setkey(DTX,Key2)
# Set cor=0 where Key2 doesn't match (OK, it's a bit of a hack!)
DTX[Key2!=V3,cor:=0]
# fill a matrix with the vector of correlations (it fits)
# original length of DT gives you the length of side
matrix(DTX[,cor],nrow(DT))
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 0.0 0.0 0.0 0.0 0.0 0
[2,] 0 1.0 0.4 0.0 0.0 0.0 0
[3,] 0 0.4 1.0 0.0 0.0 0.0 0
[4,] 0 0.0 0.0 1.0 0.4 0.3 0
[5,] 0 0.0 0.0 0.4 1.0 0.2 0
[6,] 0 0.0 0.0 0.3 0.2 1.0 0
[7,] 0 0.0 0.0 0.0 0.0 0.0 1
EDITED ABOVE - DOUBLE APPLY SLOW AS PER ROLAND'S COMMENT
How about this?
#function to return letter corresponding to number
lookup_letter<-function(let){match(let,matrix(c("A","B","C")))}
then nest 2 apply calls for each dimension of the matrix
apply(DT,1,function(x){ # call row-wise
apply(DT,1,function(y)ifelse(y[2]==x[2],M[lookup_letter(x[1]),lookup_letter(y[1])],0)) # call column-wise lookup
})
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 0.0 0.0 0.0 0.0 0.0 0
[2,] 0 1.0 0.4 0.0 0.0 0.0 0
[3,] 0 0.4 1.0 0.0 0.0 0.0 0
[4,] 0 0.0 0.0 1.0 0.4 0.3 0
[5,] 0 0.0 0.0 0.4 1.0 0.2 0
[6,] 0 0.0 0.0 0.3 0.2 1.0 0
[7,] 0 0.0 0.0 0.0 0.0 0.0 1
Probably there are better ways to lookup your correlation number, but this gives you an idea (maybe flatten M into an indexed list)