Manvendra Singh
Manvendra Singh

Reputation: 13

How to create a matrix containing pairwise ratio of two dataframes?

I have two data-frames, one containing expression values of genes (n=2000) and another containing expression values of microRNA (n=350). I want to calculate the ratio of each microRNA with each gene and then visualize it.

Here is what I am doing:

I first created an empty data-frame

m <- as.data.frame(matrix(0, ncol = 350, nrow = 2000))

The three data-frames are m, (2000, 350) control.mRNA (2000, 1) and control.miRNA (350 , 1).

Now I am calculating their ratio with each other and filling the values into empty dataframe

for (i in 1:nrow(control.mRNA)) {
  for (j in 1:nrow(control.miRNA)) {
    m[i,j] <- control.miRNA[j]/control.mRNA[i]
  }
}

But this is not working. For multiplication there is function "crossprod" but I didn't find anything for division.

Upvotes: 1

Views: 1297

Answers (1)

Vincent Guillemot
Vincent Guillemot

Reputation: 3429

You could use outer. Here is a simpl(istic)e example:

u <- 1:5
v <- c(3,7)

outer(u, v, "/")

The result is a matrix with 5 (the # of coefs in u) rows and 2 (the # of coefs in v) columns with coefficients u[i] / v[j] in row i and col j. In order to have u[j] / v[i] in row i and col j, you could then use t, the transposition operator:

M1 <- t(outer(u, v, "/"))

@shadow judiciously pointed out that outer takes vectors as arguments, and not matrices. This could easily be handled by converting the matrices to vectors first.

Let's take the same example as before, but with U and V two matrices instead of just vectors:

U <- matrix(1:5)
V <- matrix(c(3,7))
M2 <- t( outer(drop(U), drop(V), "/") )

Another solution is to transform U and V a little bit and use the matrix multiplication operator %*%:

M3 <- t( U %*% t(1/V) )

Upvotes: 1

Related Questions