Highlight cells in heatmap - r

I am currently trying to set up a heatmap of a matrix and highlight specific cells, based on two other matrices.
An example:
> SOI
NAP_G021 NAP_G033 NAP_G039 NAP_G120 NAP_G122
2315101 59.69418 27.26002 69.94698 35.22521 38.63995
2315102 104.15294 76.70379 114.72999 97.35930 79.46014
2315104 164.32822 61.83898 140.99388 63.25482 105.48041
2315105 32.15792 21.03730 26.89965 36.25943 40.46321
2315103 74.67434 82.49875 133.89709 93.17211 35.53019
> above150
NAP_G021 NAP_G033 NAP_G039 NAP_G120 NAP_G122
2315101 0 0 0 0 0
2315102 0 0 0 0 0
2315104 1 0 0 0 0
2315105 0 0 0 0 0
2315103 0 0 0 0 0
> below30
NAP_G021 NAP_G033 NAP_G039 NAP_G120 NAP_G122
2315101 0 1 0 0 0
2315102 0 0 0 0 0
2315104 0 0 0 0 0
2315105 0 1 1 0 0
2315103 0 0 0 0 0
Now I create a normal heatmap:
heatmap(t(SOI), Rowv = NA, Colv = NA)
Now what I want to do is highlight the cells, that have a 1 in above150 with a frame of one colour (e.g. blue), whilst the cells with a 1 in below30 should get a red frame. Of couse all matrices are equal sized as they are related. I know that I can add things to the heatmap after processing via add.expr, but so far I just managed to create full ablines that span the whole heatmap => not what I'm looking for.
If anybody has any suggestions I would be delighted.

When add.expr is called the plot is set so that the centre of the cells is at unit integer values. Try add.expr=points(1:5,1:5) to see. Now all you need to do is write a function that draws boxes (help(rect)) with the colours you need, at the half-integer coordinates.
Try this:
set.seed(310366)
nx=5
ny=6
SOI=matrix(rnorm(nx*ny,100,50),nx,ny)
colnames(SOI)=paste("NAP_G0",sort(as.integer(runif(ny,10,99))),sep="")
rownames(SOI)=sample(2315101:(2315101+nx-1))
above150 = SOI>150
below30=SOI<30
makeRects <- function(tfMat,border){
cAbove = expand.grid(1:nx,1:ny)[tfMat,]
xl=cAbove[,1]-0.49
yb=cAbove[,2]-0.49
xr=cAbove[,1]+0.49
yt=cAbove[,2]+0.49
rect(xl,yb,xr,yt,border=border,lwd=3)
}
heatmap(t(SOI),Rowv = NA, Colv=NA, add.expr = {
makeRects(above150,"red");makeRects(below30,"blue")})

Related

How to import and transform adjacency matrix to R edge list?

A sample of my data can be seen below. The data contains information about ties between organizations (over 2000 organizations, the csv file has 0s and 1s, and empty cells)
A2654 B0004 B0188 B1278 B1372 B1722 B2503
A2654 0 1 0 0 0 1 0
B0004 1 0 0 0 0 1 0
B0188 0 0 0 0 0 0 0
B1278 0 0 0 0 0 0 0
B1372 0 0 0 0 0 0 0
B1722 1 1 0 0 0 0 0
(1) The first problem is that I can't import this data (.csv) into R
I runt the following code dt <- read_csv2("Org_ties.csv") The problem here is that while in the csv file the first column is left empty (it should be) -- when reading it into R, read_csv() generates a label for this column "X1". I do this in order to run the next code: g=graph_from_adjacency_matrix(dtmtrx, mode="directed", weighted = T) to produce a graph. However, I get the error message below. I think it has to do with the fact that I can't read it properly.
graph.adjacency.dense(adjmatrix, mode = mode, weighted = weighted, :
not a square matrix
In addition: Warning message:
In mde(x) : NAs introduced by coercion
(2) Another puzzling thing is that I cannot seem to transform the current data structure into an edge list. How can I do that? The edge list looks something like this
V1 V2 weight
A2654 B0004 1
A2654 B0188 0
A2654 B1278 0
A2654 B1372 0
A2654 B1722 1

Determine Row Number based on Nonzero Elements

I am currently working with about 301 rows of data and want to determine the earliest point at which only a few particular columns are nonzero. However, I also want to ensure that this does not change. For example, the two columns are nonzero, while all other columns are zero, then later in the dataframe other columns are nonzero as well, this would mean that I would have to determine a later point which is "correct".
I have the data:
1 x y z xx xy xz
292 0 -8.965140 9.596890 0 0 0 -0.03147483
293 0 -9.079889 9.645991 0 0 0 -0.02722520
294 0 -8.967767 9.597826 0 0 0 0
295 0 -9.090561 9.650230 0 0 0 -0.02685287
296 0 -9.081568 9.646105 0 0 0 -0.02716237
297 0 0.000000 0.000000 0 0 0 0.00000000
298 0 0.000000 0.000000 0 0 0 0.00000000
299 0 -9.098568 9.628576 0 0 0 -0.02654466
300 0 -9.089815 9.646099 0 0 0 -0.02681748
301 0 -8.998078 9.605140 0 0 0 0
As you can see, only the variables x and y are selected for row 294, however, the xz variable contains values after that until the 301 row. Is it possible to develop a function which tells me at which point is the minimum row where I see only x and y as nonzero and it remains that way until the final row of the dataframe?
I'm sorry if it's difficult to understand the question, I found it difficult asking how exactly to accomplish this issue.
EDIT: I presume I could use something like
which((df$x != 0 & df$y != 0 &
(df[, 1] | df[, 4] == 0))
but then I need to somehow expand the second or statement to all columns of df.
Thanks in advance.

How to fix rows order with pheatmap?

I have generate a heatmap with pheatmap and for some reasons, I want that the rows appear in a predefined order.
I see in previous posts that the solution is to set the paramater cluster_row to FALSE, and to order the matrix in the order we want, like this in my case:
Otu0085 Otu0086 Otu0087 Otu0088 Otu0091
AB200 0 0 0 0 0
2 91 0 2 1 0
20CF360 0 1 0 1 0
19CF359 0 0 0 2 0
11VP12 0 0 0 0 155
11VP04 4 1 0 0 345
However, when I do:
pheatmap(shared,cluster_rows = F)
My rows are sorted alphabetically, like this:
10CF278a
11
11AA07
11CF278b
11VP03
11VP04
11VP05
11VP06
11VP08
11VP09
ANy suggestions would be welcome
Thank's by advance

adding elements with same name in a matrix

I have two matrices
Mdates<-c("8Q1","8Q2","8Q3","8Q4","9Q1","9Q2","9Q3","9Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","14Q1","14Q2")
Cr<-matrix(c("14Q2","13Q2","14Q2","14Q1","13Q4","13Q4","12Q4","13Q3","13Q4","12Q3","14Q2",12867.8,12710.7,10746.9,9634.4,8238.5,7835.2,7315.6,7263.1,7002.7,6104.8,5759.3),ncol=2,byrow=FALSE)
I add all the things with the same name in Cr and put it under the same column name in Mdates, so idealy it would look like this:
8Q1 8Q2 8Q3 8Q4 9Q1 9Q2 9Q3 9Q4 10Q1 10Q2 10Q3 10Q4 11Q1 11Q2 11Q3 11Q4 12Q1 12Q2 12Q3 12Q4 13Q1 13Q2 13Q3 13Q4 14Q1 14Q2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6104.8 7315.6 0 12710.7 7263.1 15241.3 9634.4 29373.9
You could try:
res <- tapply(as.numeric(Cr[,2]), factor(Cr[,1], levels=unique(Mdates)), FUN=sum)
res[is.na(res)] <- 0
res
# 8Q1 8Q2 8Q3 8Q4 9Q1 9Q2 9Q3 9Q4 10Q1 10Q2 10Q3 10Q4 11Q1
# 0 0 0 0 0 0 0 0 0 0 0 0 0
#11Q2 11Q3 11Q4 12Q1 12Q2 12Q3 12Q4 13Q1 13Q2 13Q3 14Q1 14Q2
# 0 0 0 0 0 6105 7316 0 12711 7263 9634 29374
I think the following does it.
First it selects the elements in Cr that are found in Mdates:
A<-Cr[ ,1]
B<-which(A %in% Mdates)
Crnew<-Cr[B, ]
The following step provides the summed values for each category:
fac <- as.factor(Crnew[ ,1])
num <- as.numeric(Crnew[ ,2])
x <-data.frame(fac, num)
tapply(x$num, x$fac, FUN=sum)

Lossy conversion Matrix -> Quaternion -> Matrix

I have a box defined by 8 points. From those points, I calculate axes and create rotation matrix as follows:
axis[0], axis[1], axis[2]
mat =
{
axis[0].x axis[1].x axis[2].x 0
axis[0].y axis[1].y axis[2].y 0
axis[0].z axis[1].z axis[2].z 0
0 0 0 1
}
I have particular rotation matrix:
{
-1 0 0 0
0 0 1 0
0 -1 0 0
0 0 0 1
}
As best of my knowledge, this is a valid rotation matrix. Its inversion is equal to its transposition.
Now I would like to store this matrix as a quaternion. But later, I need rotation matrix to be recreated from this quaternion. I believe that convertsion from matrix to quaternion and back to matrix should be an identity transform and I should get the same matrix that I had in the beginning (maybe with very small numerical errors).
But this seems not to be the case. Both SlimDX (C#) and my propertiary math library (C++) return invalid matrix.
First, quaternion that I receive:
C#: 0, 0, 0.70710676908493, 0
C++: 0, -0.707107, 0, 0
And matrix created from this quaternion:
C#:
0 0 0 0
0 0 0 0
0 0 1 0
0 0 0 1
C++:
0 0 0 0
0 1 0 0
0 0 0 0
0 0 0 1
Why is this wrong?
I've also tried this: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf but it gave me bad results as well.
The matrix you gave isn't a rotation matrix, it's a reflection matrix because its determinant is -1. See the definition on Wikipedia. You can tell something isn't right because you should get a unit quaternion, and yet the one you're getting back only has length 1/sqrt(2).
Try using a 4x4 matrix. I'm not matrix math expert, but I've never used 3x3 matrices when dealing with 3D graphics. I believe the extra dimension is for normalization, or something like that.

Resources