# Is there an R function that will compute the cosine dissimilarity matrix?

I would like to make a heatmap with row clustering based on cosine distances. I'm using R and heatmap.2() for making the figure. I can see that there's a dist parameter in heatmap.2 but I cannot find a function to generate the cosine dissimilarity matrix. The builtin dist function doesn't support cosine distances, I also found a package called arules with a dissimilarity() function but it only works on binary data.

-
It may be faster to write your own cosine dissimilarity function. – Max Jul 3 '12 at 12:45
Cosine is similarity, not dissimilarity. You can, however, turn cosine into euclidean distance of scaled data: d=sqrt(2*(1-cos)). – ttnphns Jul 3 '12 at 14:51

As @Max indicated in the comments (+1) it would be simpler to "write your own" than to spend time looking for it somewhere else. As we know, the cosine similarity between two vectors $A,B$ of length $n$ is

$$C = \frac{ \sum \limits_{i=1}^{n}A_{i} B_{i} }{ \sqrt{\sum \limits_{i=1}^{n} A_{i}^2} \cdot \sqrt{\sum \limits_{i=1}^{n} B_{i}^2} }$$

which is straightforward to generate in R. Let X be the matrix where the rows are the values we want to compute the similarity between. Then we can compute the similarity matrix with the following R code:

cos.sim <- function(ix)
{
A = X[ix[1],]
B = X[ix[2],]
return( sum(A*B)/sqrt(sum(A^2)*sum(B^2)) )
}
n <- nrow(X)
cmb <- expand.grid(i=1:n, j=1:n)
C <- matrix(apply(cmb,1,cos.sim),n,n)


Then the matrix C is the cosine similarity matrix and you can pass it to whatever heatmap function you like (the only one I'm familiar with is image()).

-
 Thanks, this is helpful. Actually, I don't want to plot the matrix itself but rather have a distance function for clustering of another heatmap that I have. – Greg Slodkowicz Jul 5 '12 at 12:01 @GregSlodkowicz, OK well perhaps you can pass this matrix to the function you're using. Also, if you've found this answer helpful please consider an upvote (or accepting the answer if you consider it definitive) :) – Macro Jul 5 '12 at 12:26 Great, thanks to your reply and ttnphns's comment I was able to do what I want. Now I would like to have a different metric when clustering rows than when clustering columns but maybe that's pushing it... – Greg Slodkowicz Jul 7 '12 at 10:20