---
title: "esApply Introduction"
author:
- name: "R. Gentleman"
- name: "V. Carey"
- name: "M. Morgan"
- name: "S. Falcon"
- name: "H. Khan"
  affiliation: "Vignette translation from Sweave to Rmarkdown / HTML"
date: "`r format(Sys.time(), '%d %B, %Y')`"
package: Biobase
vignette: >
  %\VignetteIndexEntry{esApply Introduction}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
output:
  BiocStyle::html_document
---

# A note on `esApply` {#a-note-on-esapply .unnumbered}

`ExpressionSet`s are complex objects. `exprs(ExpressionSet)` produces $G \times N$, where $G$ is the number of genes on a chip and $N$ is the number of tissues analyzed, and `pData(ExpressionSet)` produces $N \times p$, where $p$ is the number of phenotypic or demographic, etc., variables collected.

Abstractly, we are often interested in evaluating functions $f(y;x)$ where $y$ is an $N$-vector of expression results for a specific gene and $x$ is an $N$-dimensional structure, coordinated with $y$, that distinguishes elements of $y$ for processing in the function $f$. A basic problem is to guarantee that the $j$th element of $y$ is correctly associated with the $j$th component of $x$.

As an example, let's consider `sample.ExpressionSet`, which is an *ExpressionSet* supplied with Biobase. We will print a little report, then the first $N$-vector of gene expressions and some covariate data:

```{r message=FALSE, echo=FALSE}
library(Biobase)
data(sample.ExpressionSet)
```

```{r}
sample.ExpressionSet
exprs(sample.ExpressionSet)[1,]
pData(sample.ExpressionSet)[1:2,1:3]
```

Now let's see how expressions and a covariate are related:

```{r}
rbind(exprs(sample.ExpressionSet[1,]),
            sex <- t(pData(sample.ExpressionSet))[1,])
```

A function that evaluates the difference in median expression across strata defined using an abstract covariate `x` is

```{r}
medContr <- function( y, x ) {
    ys <- split(y,x)
    median(ys[[1]]) - median(ys[[2]])
 }
```

We can apply this to a small *ExpressionSet* that gives back the data listed above:

```{r}
apply(exprs(sample.ExpressionSet[1,,drop=F]), 1, medContr, pData(sample.ExpressionSet)[["sex"]])
```

That's a bit clumsy. This is where `esApply` comes in. We pay for some simplicity by following a strict protocol for the definition of the statistical function to be applied.

```{r}
medContr1 <- function(y) {
   ys <- split(y,sex)
   median(ys[[1]]) - median(ys[[2]])
}
esApply( sample.ExpressionSet, 1, medContr1)[1]
```

The manual page on `esApply` has a number of additional examples that show how applicable functions can be constructed and used. The important thing to note is that the applicable functions *know* the names of the covariates in the `pData` dataframe.

This is achieved by having an environment populated with all the variables in *phenoData(ExpressionSet)* put in as the environment of the function that will be applied. If that function already has an environment we retain that but in the second position. Thus, there is some potential for variable shadowing.

# Session Information

The version number of R and packages loaded for generating the vignette were:

```{r echo=FALSE}
sessionInfo()
```
