Author: Julia Fukuyama
Date: 2022-12-07

# adaptiveGPCA vignette

#### Julia Fukuyama

#### 2022-12-07

## Overview

### Adaptive gPCA

Adaptive gPCA (Fukuyama, J. (2017)) is a flexible method for incorporating side information about the variables into principal components analysis. The method has a single parameter, \(r\), which controls how much weight to give to the side information: \(r = 0\) corresponds to standard PCA (the side information is not used at all), and \(r = 1\) corresponds to the maximum amount of weight on the side information.

The output from adaptive gPCA is analogous to that given by PCA: we get representations of the samples and the variables, which can be visualized as either independently or as a biplot. The difference with standard PCA is that, assuming \(r > 0\), the variable loadings are regularized so that similar variables are encouraged to have similar loadings on the principal axes.

### Package functionality

There are two main ways of using this package. The function `adaptivegpca` will choose the value of \(r\) automatically, while the function `gpcaFullFamily` produces analogous output for the full range of values of \(r\), which is then chosen manually. We will illustrate both methods in this vignette.

Although adaptive gPCA can be applied more generally, the method was developed to incorporate phylogenetic structure in microbiome data analysis, and so there are also functions to interface with phyloseq objects and functions to visualize adaptive gPCA output along with a phylogenetic tree.

### Data

The data set we will use to illustrate the functionality of this package is an antibiotic time course study1. In this experiment, three subjects were given two courses of antibiotics, and the abundances of bacteria in the gut microbiome were measured before, during, and after each course of antibiotics. The data is stored in a phyloseq object called `AntibioticPhyloseq`, which contains variance-stabilized and centered abundances on the `otu_table` slot, a phylogenetic tree describing the relationships between the bacterial species measured in the `phy_tree` slot, and information about the samples in the `sample_data` slot. We want a low-dimensional representation of the samples which takes into account the phylogenetic similarities between the bacteria, which is what adaptive gPCA will provide for us.

## Fitting an agpca model

Now that we have described the data we will be using, we will show how to use the package. The first step is to load the required packages and data.

    library(adaptiveGPCA)
    library(ggplot2)
    library(phyloseq)
    data(AntibioticPhyloseq)
    theme_set(theme_bw())

Next, we create the inputs required for the `adaptivegpca` function. If we have a `phyloseq` object containing taxon abundances and a phylogenetic tree, the function `processPhyloseq` will create a list with the following elements:

- A centered data matrix, stored as `X` in the output.

- A similarity matrix based on the phylogeny, stored as `Q` in the output.

- A vector of weights, stored as `weights`. The weights are only relevant for correspondence analysis, so if the function is invoked with `ca = FALSE` (the default), the weights vector will be a vector containing only 1’s and can be ignored.

    pp = processPhyloseq(AntibioticPhyloseq)

Next, we pass our data matrix and our similarity matrix to the `adaptivegpca` function. The arguments to `adaptivegpca` are

- `X`: A centered data matrix.

- `Q`: A symmetric, positive definite matrix describing the similarities between the variables.

- `k`: The number of axes to keep, defaults to 2.

- `weights`: A vector with sample weights, defaults to a vector of all 1’s (equal weights on each sample).

The matrices `X` and `Q` will be generated from a phyloseq object using the OTU table and the phylogenetic tree with the `processPhyloseq` function. If you have another kind of data, you can generate these matrices yourself. Below we use the output from `processPhyloseq` to fit an adaptive gPCA model.

    out.agpca = adaptivegpca(pp$X, pp$Q, k = 2)

The output from the `adaptivegpca` function is stored in an object of class `adaptivegpca`, which has some generic printing and plotting functions associated with it. As such, if we just print out the object, it will give us some basic information about the results, namely the number of axes, the value of \(r\) chosen, and the fraction of the variance explained by the top axes.

    out.agpca

    ## An object of class adaptivegpca
    ## -------------------------------
    ## Number of axes: 2
    ## Value of r chosen: 0.462
    ## Fraction of variance explained
    ## by first 2 axes:
    ## 0.195 0.156

The output is a list with several elements. These are:

- `U`: The sample scores on the principal axes.

- `V`: The variable loadings before rotation. These are not used for plotting — they need to be rotated into the space of the samples for the biplot representation.

- `QV`: The variable loadings rotated to be in the same space as the sample scores. These are the variable loadings that should be plotted for a biplot representation of the samples and the variables.

- `vars`: The variances along the principal axes.

- `r`: The value of \(r\) chosen by adaptivegpca, corresponding to how much regularization to perform according to the structure of the variables. \(r = 0\) is standard PCA (variable structure is not considered at all), and \(r = 1\) is the maximal amount of regularization.

- `evals`: The eigenvalues of the modified similarity matrix. This is described in more detail in the paper, but it is an alternate way of understanding how much regularization is performed by the method. The larger the top eigenvalues are compared with the subsequent ones, the more regularization there is toward the top eigenvectors of the similarity matrix.

## Plotting the output

We can also plot the output from `adaptivegpca` using a generic plotting function. By default, this will produce a scree plot, as shown below:

    plot(out.agpca)

The plotting function has a `type` argument, which can be either `scree`, `samples`, or `variables`. `type = scree` will give a plot showing the fraction of the variance explained by each of the axes, `type = samples` will show the sample scores along the principal axes, and `type = variables` will show the variable loadings on the principal axes. The `axes` argument allows the user to specify which axes to plot, by default these are axes 1 and 2.

    plot(out.agpca, type = "samples", axes = c(1,2))

    plot(out.agpca, type = "variables", axes = c(1,2))

Finally, the `inspectTaxonomy` function allows interactive inspection of the taxa or variables plot, assuming you started the analysis with a phyloseq object. This function will open a browser window with a representation of the phylogenetic tree and the taxon loadings on the adaptive gPCA axes. Taxa in this plot can be selected by “brushing” the plot (drawing a rectangular box), and the selected taxa will be highlighted on the phylogenetic tree and their taxonomic assignments will be printed below. An example call is given below:

    inspectTaxonomy(out.agpca, AntibioticPhyloseq)

The arguments to `inspectTaxonomy` are

- `agpcafit`: The output from `adaptivegpca`.

- `physeq`: A phyloseq object with a taxonomy table and a phylogenetic tree. Should be the same one used for for the adaptive gPCA fit.

- `axes`: Which axes to plot. Defaults to the first two axes.

- `br.length`: Should the tree include branch lengths? The trees tend to look better when the branches are all plotted as being the same length, so this defaults to `FALSE`.

- `height`: The height of the plotting area in pixels. Defaults to 600.

If you click the “done” button in the browser window, the app will close and the function will return a table describing the taxonomy, position along selected axes, and names of the selected taxa.

## Interactive choice of \(r\)

We can also choose the value of \(r\) manually. In the previous section, we described how to use the `adaptivegpca` function, which chooses the value of \(r\) automatically, but if we would like to see the results for different values of \(r\) and to choose one manually, we can first use the `gpcaFullFamily` function to create a full set of models and then use the `visualizeFullFamily` function to visualize the biplots for each value of \(r\).

`gpcaFullFamily` takes the same arguments as `adaptivegpca`, along with some additional arguments describing the form of the output.

The `visualizeFullFamily` function is a shiny gadget. Calling this function will open a browser window where you can visualize the data set for a range of values of \(r\). Clicking “done” in this window will give as output an object of the same format as that given by the `adaptivegpca` function, the difference being that the value of \(r\) was chosen manually instead of automatically. The `sample_data`/`sample_mapping` and `var_data`/`var_mapping` arguments allow you to customize the visualization. Without these arguments, the first two axes will be plotted for both the samples and the variables. If you include these arguments, you can customize the plots by providing aesthetic mappings for ggplot. Note that the code below is only included as an example and not evaluated in the vignette.

    out.ff = gpcaFullFamily(pp$X, pp$Q, k = 2)
    out.agpca = visualizeFullFamily(out.ff,
                        sample_data = sample_data(AntibioticPhyloseq),
                        sample_mapping = aes(x = Axis1, y = Axis2, color = type),
                        var_data = tax_table(AntibioticPhyloseq),
                        var_mapping = aes(x = Axis1, y = Axis2, color = Phylum))

In either case, we can plot the results. This time we will do it manually, using ggplot. The sample scores on the principal axes are located in `out.agpca$U` and the loadings of the variables on the principal axes are located in `out.agpca$QV`. To plot the samples, we make a data frame that includes `out.agpca$U` and the sample data, and to plot the taxa we make a data frame containing `out.agpca$QV` and the taxonomy table.

    ggplot(data.frame(out.agpca$U, sample_data(AntibioticPhyloseq))) +
        geom_point(aes(x = Axis1, y = Axis2, color = type, shape = ind)) +
        xlab("Axis 1") + ylab("Axis 2")

    ggplot(data.frame(out.agpca$QV, tax_table(AntibioticPhyloseq))) +
        geom_point(aes(x = Axis1, y = Axis2, color = Phylum)) +
        xlab("Axis 1") + ylab("Axis 2")

## Correspondence analysis

Finally, note that the `processPhyloseq` function also has an argument `ca` (for correspondence analysis). This should be used with phyloseq objects containing raw counts, and it will process a phyloseq object so as to do an adaptive gPCA version of correspondence analysis (this entails transforming counts to relative abunadnces, computing sample weights based on the overall counts for the samples, and finally doing a weighted centering of the relative abundances).

1. Dethlefsen, L., and D. A. Relman. “Incomplete recovery and individualized responses of the human distal gut microbiota to repeated antibiotic perturbation.” Proc Natl Acad Sci USA 108. Suppl 1 (2010): 4554-4561.↩︎