1

I am processing a special object -- SliceData object from Matrix_eQTL -- in a loop and I am wondering if it can be re-write by any function in the "apply".

Let me explain it by a toy example. First I create the toy data by the following scripts.

library(MatrixEQTL)
set.seed(5)
gene_mat = matrix(data = rnorm(200000, mean=50, sd=10), nrow = 2000, ncol = 100)
gene = SlicedData$new(gene_mat);
gene$ResliceCombined(200)

Here I have a custom function invnorm.

invnorm <- function(expression){
  return(qnorm((rank(expression, na.last="keep") - 0.5)/sum(!is.na(expression))))
}

And what I want to do is to apply this invnorm on each row of each slice of gene object which can be realized by the following scripts

for( sl in 1:length(gene) ){
    mat = gene[[sl]]
    mat = t(apply(mat, 1, invnorm))
    gene[[sl]] = mat
}

So is there any way to re-wrote this loop by any function in the apply function family? Thank you in advance.

Minky J
  • 109
  • 1
  • 6
  • 1
    Would be easier if this were reproducible. as is ```lapply(gene, function (x) t(apply(x, 1, invnorm))``` should do this pretty well. – Cole Apr 15 '20 at 00:44
  • Good idea! Have added a toy example. May I have your suggestion in a formal solution so that I can upvote and accept it? Thank you very much! – Minky J Apr 19 '20 at 12:24
  • 1
    This package uses S4 classes which means that usual ```lapply``` does not work. The good news is that your for loop should be just as fast as using ```lapply```. Plus, there's no shame in using a for loop as they are mainly there for readibility. – Cole Apr 24 '20 at 03:17
  • You revealed what I am thinking -- I am just shamed in using for loop lol. And thank you very much for your clear explanation! Do you mind just copy your comment to the answer so that I can accept it? – Minky J Apr 25 '20 at 03:13

1 Answers1

2

Normally, we could approach this by using lapply to replace your for loop.

gene = lapply(gene, function(sl) t(apply(sl, 1, invnorm)))

However, this package uses S4 classes which means that usual lapply does not work. The good news is that your for loop should be just as fast as using lapply. Plus, there's no shame in using a for loop - apply statements are mainly just syntatic sugar for readibility.

See also:

Is R's apply family more than syntactic sugar?

Cole
  • 11,130
  • 1
  • 9
  • 24