Ordination is a technique to take high-dimensional data and to represent it in a lower dimensional context.

Ordination is a collective term for multivariate techniques which summarize a multidimensional dataset in such a way that when it is projected onto a low dimensional space, any intrinsic pattern the data may possess becomes apparent upon visual inspection1.

One of the largest challenges in data analysis is the ability to understand and gain inferences from it! This is especially compounded when we have many different kinds of data describing our individual observations. For example, at a particular vernal pool, we may have measured pool size, pool depth, elevation, rainfall, temperature, canopy cover, pH, aquatic vegitation, species1 density, species2 density, etc. To describe all of these variables we could either plot all combinations of them or be a bit clever and use some ordination approaches.

For this activity, I am going to use the beer styles as a data set in explaining a couple of different types of ordination. It is available as the raw CSV file.

url <- "https://raw.githubusercontent.com/dyerlab/ENVS-Lectures/master/data/Beer_Styles.csv"
read_csv( url ) %>%
  mutate( Yeast = as.factor( Yeast ) ) -> data
summary(data)
    Styles             Yeast       ABV_Min         ABV_Max          IBU_Min         IBU_Max          SRM_Min     
 Length:100         Ale   :69   Min.   :2.400   Min.   : 3.200   Min.   : 0.00   Min.   :  8.00   Min.   : 2.00  
 Class :character   Either: 4   1st Qu.:4.200   1st Qu.: 5.475   1st Qu.:15.00   1st Qu.: 25.00   1st Qu.: 3.50  
 Mode  :character   Lager :27   Median :4.600   Median : 6.000   Median :20.00   Median : 35.00   Median : 8.00  
                                Mean   :4.947   Mean   : 6.768   Mean   :21.97   Mean   : 38.98   Mean   : 9.82  
                                3rd Qu.:5.500   3rd Qu.: 8.000   3rd Qu.:25.00   3rd Qu.: 45.00   3rd Qu.:14.00  
                                Max.   :9.000   Max.   :14.000   Max.   :60.00   Max.   :120.00   Max.   :30.00  
    SRM_Max          OG_Min          OG_Max          FG_Min          FG_Max     
 Min.   : 3.00   Min.   :1.026   Min.   :1.032   Min.   :0.998   Min.   :1.006  
 1st Qu.: 7.00   1st Qu.:1.040   1st Qu.:1.052   1st Qu.:1.008   1st Qu.:1.012  
 Median :17.00   Median :1.046   Median :1.060   Median :1.010   Median :1.015  
 Mean   :17.76   Mean   :1.049   Mean   :1.065   Mean   :1.009   Mean   :1.016  
 3rd Qu.:22.00   3rd Qu.:1.056   3rd Qu.:1.075   3rd Qu.:1.010   3rd Qu.:1.018  
 Max.   :40.00   Max.   :1.080   Max.   :1.130   Max.   :1.020   Max.   :1.040  

These data give ranges of values but it is probably easier if we just take the midpoint of the range.

data %>%
  mutate( ABV=( ABV_Max+ABV_Min)/2,
          IBU=( IBU_Max+IBU_Min)/2,
          SRM=( SRM_Max+SRM_Min)/2,
          OG=( OG_Max+OG_Min)/2,
          FG=( FG_Max+FG_Min)/2 )  %>%
  select( Styles, Yeast, ABV, IBU, SRM, OG, FG) -> beers
summary( beers)
    Styles             Yeast         ABV              IBU             SRM              OG              FG       
 Length:100         Ale   :69   Min.   : 2.850   Min.   : 5.00   Min.   : 2.50   Min.   :1.030   Min.   :1.003  
 Class :character   Either: 4   1st Qu.: 4.900   1st Qu.:21.38   1st Qu.: 5.00   1st Qu.:1.047   1st Qu.:1.010  
 Mode  :character   Lager :27   Median : 5.300   Median :26.25   Median :12.75   Median :1.052   Median :1.012  
                                Mean   : 5.857   Mean   :30.48   Mean   :13.79   Mean   :1.057   Mean   :1.013  
                                3rd Qu.: 6.750   3rd Qu.:37.50   3rd Qu.:18.00   3rd Qu.:1.065   3rd Qu.:1.014  
                                Max.   :11.500   Max.   :90.00   Max.   :35.00   Max.   :1.100   Max.   :1.029  

Excellent. If we look a the data now, we can see that there are a moderate amount of correlation between data types and all of the characteristics are spread reasonably well across the Yeast types. Here is a pairwise plot of all the data using the GGally::ggpairs() function.

library(GGally)
beers %>%
  select( -Styles ) %>%
  ggpairs() 

Principle Component Analyses

Principle component analysis (PCA) is a translation of the original data into new coordinate spaces. This has absolutely nothing to do with the relationship among the data themselves but is more of a way to create new coordinates for each data point under the following criteria:
1. The number of axes in the translated data are the same as the number of axes in the original data. 2. Axes are chosen by taking all the data and finding transects through it that account for the broadest variation in the data. 3. Each axis is defined as a linear combination of the original axes. 3. Subsequent axes must be orthoganal to all previous ones (e.g., at 90\(\deg\) angles). 4. The amount of the total variation in the system can be partitioned by these new axes and they are ordered from those that explain the most variation to those who explain the least.

An exmaple of this rotation is given below.

A rotation of 2-dimenational data from the original coordinate space (represented by the x- and y-axes) onto synthetic principal component (the red axes). The rotation itself maximizes the distributional width of the data (depicted as density plots in grey for the original axes and red for the rotated axes).

To conduct this rotation on our data, we use the function prcomp(). It does the rotation and returns an analysis object that has all the information we need in it.

pc.fit <- prcomp(beers[,3:7])
names( pc.fit)
[1] "sdev"     "rotation" "center"   "scale"    "x"       

If we look at the raw analysis output, we see a summary of the amount of data explained by each of the axes as well as the loadings (e.g., the linear combinations of the original data that translate the old coordinates into the new ones).

pc.fit
Standard deviations (1, .., p=5):
[1] 17.407474934  8.593744939  1.537237291  0.004779020  0.001954314

Rotation (n x k) = (5 x 5):
             PC1           PC2          PC3           PC4           PC5
ABV 0.0500642463  0.0005333582 -0.998701196 -8.619900e-03 -3.860675e-03
IBU 0.9773017876  0.2060831568  0.049101404  9.539617e-06  2.089354e-05
SRM 0.2058507906 -0.9785343146  0.009797993 -1.998978e-04  8.053623e-05
OG  0.0004724918 -0.0001184112 -0.009304602  8.330098e-01  5.531798e-01
FG  0.0001261491 -0.0001705335 -0.001548091  5.531911e-01 -8.330529e-01

We can plot these and by default it shows the variation explained by each axis.

plot( pc.fit )

This rotation seems to be able to produce axes that account for a lot of the underyling variation. Here is a synopsis:

format( pc.fit$sdev / sum( pc.fit$sdev ), digits=3)
[1] "6.32e-01" "3.12e-01" "5.58e-02" "1.73e-04" "7.09e-05"

So, the first axis describes 63% of the variation and the second describes 31%, etc.

We can plot the original data points, projected into this new coordiante space.

data.frame( predict( pc.fit )) %>%
  mutate( Yeast = beers$Yeast, 
          Style = beers$Styles ) -> predicted

ggplot( predicted ) + 
  geom_point( aes(PC1, PC2, color=Yeast), size=4 )

Principal Coordinate Analyses (PCoA)

Non-metric Multiple Dimensional Scaling (NMDS)

Using Rotated Data


  1. Pielou EC, (1984) The interpretation of ecological data: A primer on classification and ordination. 288pg. ISBN: 978-0-471-88950-2↩︎

LS0tCnRpdGxlOiAiT3JkaW5hdGlvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKT3JkaW5hdGlvbiBpcyBhIHRlY2huaXF1ZSB0byB0YWtlIGhpZ2gtZGltZW5zaW9uYWwgZGF0YSBhbmQgdG8gcmVwcmVzZW50IGl0IGluIGEgbG93ZXIgZGltZW5zaW9uYWwgY29udGV4dC4gIAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoIHJnbCApCmtuaXRyOjprbml0X2hvb2tzJHNldCggd2ViZ2wgPSBob29rX3dlYmdsICkKa25pdHI6Om9wdHNfY2h1bmskc2V0KCBlY2hvID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduID0gImNlbnRlciIsIAogICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDYsIAogICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQ9NSwgCiAgICAgICAgICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZT1GQUxTRSkKbGlicmFyeSggdGlkeXZlcnNlICkKdGhlbWVfc2V0KCB0aGVtZV9idyggYmFzZV9zaXplID0gMTgpICkKYGBgCgo+IE9yZGluYXRpb24gaXMgYSBjb2xsZWN0aXZlIHRlcm0gZm9yIG11bHRpdmFyaWF0ZSB0ZWNobmlxdWVzIHdoaWNoIHN1bW1hcml6ZSBhIG11bHRpZGltZW5zaW9uYWwgZGF0YXNldCBpbiBzdWNoIGEgd2F5IHRoYXQgd2hlbiBpdCBpcyBwcm9qZWN0ZWQgb250byBhIGxvdyBkaW1lbnNpb25hbCBzcGFjZSwgYW55IGludHJpbnNpYyBwYXR0ZXJuIHRoZSBkYXRhIG1heSBwb3NzZXNzIGJlY29tZXMgYXBwYXJlbnQgdXBvbiB2aXN1YWwgaW5zcGVjdGlvblteMV0uCgpPbmUgb2YgdGhlIGxhcmdlc3QgY2hhbGxlbmdlcyBpbiBkYXRhIGFuYWx5c2lzIGlzIHRoZSBhYmlsaXR5IHRvIHVuZGVyc3RhbmQgYW5kIGdhaW4gaW5mZXJlbmNlcyBmcm9tIGl0ISAgVGhpcyBpcyBlc3BlY2lhbGx5IGNvbXBvdW5kZWQgd2hlbiB3ZSBoYXZlIG1hbnkgZGlmZmVyZW50IGtpbmRzIG9mIGRhdGEgZGVzY3JpYmluZyBvdXIgaW5kaXZpZHVhbCBvYnNlcnZhdGlvbnMuICBGb3IgZXhhbXBsZSwgYXQgYSBwYXJ0aWN1bGFyIHZlcm5hbCBwb29sLCB3ZSBtYXkgaGF2ZSBtZWFzdXJlZCBwb29sIHNpemUsIHBvb2wgZGVwdGgsIGVsZXZhdGlvbiwgcmFpbmZhbGwsIHRlbXBlcmF0dXJlLCBjYW5vcHkgY292ZXIsIHBILCBhcXVhdGljIHZlZ2l0YXRpb24sIHNwZWNpZXMxIGRlbnNpdHksIHNwZWNpZXMyIGRlbnNpdHksIGV0Yy4gIFRvIGRlc2NyaWJlIGFsbCBvZiB0aGVzZSB2YXJpYWJsZXMgd2UgY291bGQgZWl0aGVyIHBsb3QgYWxsIGNvbWJpbmF0aW9ucyBvZiB0aGVtICpvciogYmUgYSBiaXQgY2xldmVyIGFuZCB1c2Ugc29tZSBvcmRpbmF0aW9uIGFwcHJvYWNoZXMuCgpGb3IgdGhpcyBhY3Rpdml0eSwgSSBhbSBnb2luZyB0byB1c2UgdGhlIGJlZXIgc3R5bGVzIGFzIGEgZGF0YSBzZXQgaW4gZXhwbGFpbmluZyBhIGNvdXBsZSBvZiBkaWZmZXJlbnQgdHlwZXMgb2Ygb3JkaW5hdGlvbi4gIEl0IGlzIGF2YWlsYWJsZSBhcyB0aGUgcmF3IENTViBmaWxlLgoKYGBge3J9CnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2R5ZXJsYWIvRU5WUy1MZWN0dXJlcy9tYXN0ZXIvZGF0YS9CZWVyX1N0eWxlcy5jc3YiCnJlYWRfY3N2KCB1cmwgKSAlPiUKICBtdXRhdGUoIFllYXN0ID0gYXMuZmFjdG9yKCBZZWFzdCApICkgLT4gZGF0YQpzdW1tYXJ5KGRhdGEpCmBgYAoKVGhlc2UgZGF0YSBnaXZlIHJhbmdlcyBvZiB2YWx1ZXMgYnV0IGl0IGlzIHByb2JhYmx5IGVhc2llciBpZiB3ZSBqdXN0IHRha2UgdGhlIG1pZHBvaW50IG9mIHRoZSByYW5nZS4KCmBgYHtyfQpkYXRhICU+JQogIG11dGF0ZSggQUJWPSggQUJWX01heCtBQlZfTWluKS8yLAogICAgICAgICAgSUJVPSggSUJVX01heCtJQlVfTWluKS8yLAogICAgICAgICAgU1JNPSggU1JNX01heCtTUk1fTWluKS8yLAogICAgICAgICAgT0c9KCBPR19NYXgrT0dfTWluKS8yLAogICAgICAgICAgRkc9KCBGR19NYXgrRkdfTWluKS8yICkgICU+JQogIHNlbGVjdCggU3R5bGVzLCBZZWFzdCwgQUJWLCBJQlUsIFNSTSwgT0csIEZHKSAtPiBiZWVycwpzdW1tYXJ5KCBiZWVycykKYGBgCgpFeGNlbGxlbnQuICBJZiB3ZSBsb29rIGEgdGhlIGRhdGEgbm93LCB3ZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIGEgbW9kZXJhdGUgYW1vdW50IG9mIGNvcnJlbGF0aW9uIGJldHdlZW4gZGF0YSB0eXBlcyBhbmQgYWxsIG9mIHRoZSBjaGFyYWN0ZXJpc3RpY3MgYXJlIHNwcmVhZCByZWFzb25hYmx5IHdlbGwgYWNyb3NzIHRoZSBZZWFzdCB0eXBlcy4gIEhlcmUgaXMgYSBwYWlyd2lzZSBwbG90IG9mIGFsbCB0aGUgZGF0YSB1c2luZyB0aGUgYEdHYWxseTo6Z2dwYWlycygpYCBmdW5jdGlvbi4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoR0dhbGx5KQpiZWVycyAlPiUKICBzZWxlY3QoIC1TdHlsZXMgKSAlPiUKICBnZ3BhaXJzKCkgCmBgYAoKCgojIyBQcmluY2lwbGUgQ29tcG9uZW50IEFuYWx5c2VzCgpQcmluY2lwbGUgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpIGlzIGEgdHJhbnNsYXRpb24gb2YgdGhlIG9yaWdpbmFsIGRhdGEgaW50byBuZXcgY29vcmRpbmF0ZSBzcGFjZXMuICBUaGlzIGhhcyBhYnNvbHV0ZWx5IG5vdGhpbmcgdG8gZG8gd2l0aCB0aGUgcmVsYXRpb25zaGlwIGFtb25nIHRoZSBkYXRhIHRoZW1zZWx2ZXMgYnV0IGlzIG1vcmUgb2YgYSB3YXkgdG8gY3JlYXRlIG5ldyBjb29yZGluYXRlcyBmb3IgZWFjaCBkYXRhIHBvaW50IHVuZGVyIHRoZSBmb2xsb3dpbmcgY3JpdGVyaWE6ICAKMS4gVGhlIG51bWJlciBvZiBheGVzIGluIHRoZSB0cmFuc2xhdGVkIGRhdGEgYXJlIHRoZSBzYW1lIGFzIHRoZSBudW1iZXIgb2YgYXhlcyBpbiB0aGUgb3JpZ2luYWwgZGF0YS4KMi4gQXhlcyBhcmUgY2hvc2VuIGJ5IHRha2luZyBhbGwgdGhlIGRhdGEgYW5kIGZpbmRpbmcgdHJhbnNlY3RzIHRocm91Z2ggaXQgdGhhdCBhY2NvdW50IGZvciB0aGUgYnJvYWRlc3QgdmFyaWF0aW9uIGluIHRoZSBkYXRhLgozLiBFYWNoIGF4aXMgaXMgZGVmaW5lZCBhcyBhIGxpbmVhciBjb21iaW5hdGlvbiBvZiB0aGUgb3JpZ2luYWwgYXhlcy4KMy4gU3Vic2VxdWVudCBheGVzICptdXN0IGJlKiBvcnRob2dhbmFsIHRvIGFsbCBwcmV2aW91cyBvbmVzIChlLmcuLCBhdCA5MCRcZGVnJCBhbmdsZXMpLgo0LiBUaGUgYW1vdW50IG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gaW4gdGhlIHN5c3RlbSBjYW4gYmUgcGFydGl0aW9uZWQgYnkgdGhlc2UgbmV3IGF4ZXMgYW5kIHRoZXkgYXJlIG9yZGVyZWQgZnJvbSB0aG9zZSB0aGF0IGV4cGxhaW4gdGhlIG1vc3QgdmFyaWF0aW9uIHRvIHRob3NlIHdobyBleHBsYWluIHRoZSBsZWFzdC4KCkFuIGV4bWFwbGUgb2YgdGhpcyByb3RhdGlvbiBpcyBnaXZlbiBiZWxvdy4KCiFbQSByb3RhdGlvbiBvZiAyLWRpbWVuYXRpb25hbCBkYXRhIGZyb20gdGhlIG9yaWdpbmFsIGNvb3JkaW5hdGUgc3BhY2UgKHJlcHJlc2VudGVkIGJ5IHRoZSB4LSBhbmQgeS1heGVzKSBvbnRvIHN5bnRoZXRpYyBwcmluY2lwYWwgY29tcG9uZW50ICh0aGUgcmVkIGF4ZXMpLiBUaGUgcm90YXRpb24gaXRzZWxmIG1heGltaXplcyB0aGUgZGlzdHJpYnV0aW9uYWwgd2lkdGggb2YgdGhlIGRhdGEgKGRlcGljdGVkIGFzIGRlbnNpdHkgcGxvdHMgaW4gZ3JleSBmb3IgdGhlIG9yaWdpbmFsIGF4ZXMgYW5kIHJlZCBmb3IgdGhlIHJvdGF0ZWQgYXhlcykuXShodHRwczovL2xpdmUuc3RhdGljZmxpY2tyLmNvbS82NTUzNS81MDYxMzYyMDA4Nl8yZDFmOWNhNmRkX2NfZC5qcGcpCgpUbyBjb25kdWN0IHRoaXMgcm90YXRpb24gb24gb3VyIGRhdGEsIHdlIHVzZSB0aGUgZnVuY3Rpb24gYHByY29tcCgpYC4gIEl0IGRvZXMgdGhlIHJvdGF0aW9uIGFuZCByZXR1cm5zIGFuIGFuYWx5c2lzIG9iamVjdCB0aGF0IGhhcyBhbGwgdGhlIGluZm9ybWF0aW9uIHdlIG5lZWQgaW4gaXQuCgpgYGB7cn0KcGMuZml0IDwtIHByY29tcChiZWVyc1ssMzo3XSkKbmFtZXMoIHBjLmZpdCkKYGBgCgpJZiB3ZSBsb29rIGF0IHRoZSByYXcgYW5hbHlzaXMgb3V0cHV0LCB3ZSBzZWUgYSBzdW1tYXJ5IG9mIHRoZSBhbW91bnQgb2YgZGF0YSBleHBsYWluZWQgYnkgZWFjaCBvZiB0aGUgYXhlcyBhcyB3ZWxsIGFzIHRoZSBsb2FkaW5ncyAoZS5nLiwgdGhlIGxpbmVhciBjb21iaW5hdGlvbnMgb2YgdGhlIG9yaWdpbmFsIGRhdGEgdGhhdCB0cmFuc2xhdGUgdGhlIG9sZCBjb29yZGluYXRlcyBpbnRvIHRoZSBuZXcgb25lcykuCgpgYGB7cn0KcGMuZml0CmBgYAoKV2UgY2FuIHBsb3QgdGhlc2UgYW5kIGJ5IGRlZmF1bHQgaXQgc2hvd3MgdGhlIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgZWFjaCBheGlzLgoKYGBge3J9CnBsb3QoIHBjLmZpdCApCmBgYAoKVGhpcyByb3RhdGlvbiBzZWVtcyB0byBiZSBhYmxlIHRvIHByb2R1Y2UgYXhlcyB0aGF0IGFjY291bnQgZm9yIGEgbG90IG9mIHRoZSB1bmRlcnlsaW5nIHZhcmlhdGlvbi4gIEhlcmUgaXMgYSBzeW5vcHNpczoKCmBgYHtyfQpmb3JtYXQoIHBjLmZpdCRzZGV2IC8gc3VtKCBwYy5maXQkc2RldiApLCBkaWdpdHM9MykKYGBgCgpTbywgdGhlIGZpcnN0IGF4aXMgZGVzY3JpYmVzIDYzJSBvZiB0aGUgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIGRlc2NyaWJlcyAzMSUsIGV0Yy4KCldlIGNhbiBwbG90IHRoZSBvcmlnaW5hbCBkYXRhIHBvaW50cywgcHJvamVjdGVkIGludG8gdGhpcyBuZXcgY29vcmRpYW50ZSBzcGFjZS4KCmBgYHtyfQpkYXRhLmZyYW1lKCBwcmVkaWN0KCBwYy5maXQgKSkgJT4lCiAgbXV0YXRlKCBZZWFzdCA9IGJlZXJzJFllYXN0LCAKICAgICAgICAgIFN0eWxlID0gYmVlcnMkU3R5bGVzICkgLT4gcHJlZGljdGVkCgpnZ3Bsb3QoIHByZWRpY3RlZCApICsgCiAgZ2VvbV9wb2ludCggYWVzKFBDMSwgUEMyLCBjb2xvcj1ZZWFzdCksIHNpemU9NCApCgpgYGAKCiMjIFByaW5jaXBhbCBDb29yZGluYXRlIEFuYWx5c2VzIChQQ29BKQoKCgoKCgojIyBOb24tbWV0cmljIE11bHRpcGxlIERpbWVuc2lvbmFsIFNjYWxpbmcgKE5NRFMpCgpgYGB7cn0KbGlicmFyeSggdmVnYW4gKQpiZWVycyAlPiUKICBzZWxlY3QoIC1TdHlsZXMsIC1ZZWFzdCApICU+JQogIG1ldGFNRFMoIHRyYWNlID0gRkFMU0UgKSAlPiUKICBvcmRpcGxvdCggKQpgYGAKCgoKIyMgVXNpbmcgUm90YXRlZCBEYXRhCgoKCgoKW14xXTogUGllbG91IEVDLCAoMTk4NCkgVGhlIGludGVycHJldGF0aW9uIG9mIGVjb2xvZ2ljYWwgZGF0YTogQSBwcmltZXIgb24gY2xhc3NpZmljYXRpb24gYW5kIG9yZGluYXRpb24uICAyODhwZy4gSVNCTjogIVs5NzgtMC00NzEtODg5NTAtMl0oaHR0cHM6Ly93d3cud2lsZXkuY29tL2VuLXVzL1RoZStJbnRlcnByZXRhdGlvbitvZitFY29sb2dpY2FsK0RhdGElM0ErQStQcmltZXIrb24rQ2xhc3NpZmljYXRpb24rYW5kK09yZGluYXRpb24tcC05NzgwNDcxODg5NTAyKQoKCg==