These documents provide some examples of triad data visualization primarily using the packages ggtern, compositions and robCompositions. The ggtern package is an extension of R’s ggplot2 package offering many specialized visualization options for presenting 3-part compositional data within ternary plots. The author, Nicholas Hamilton, offers many examples with accompanying code. Compositions and robCompositions provide custom functions to transform, analyse, and model compositional data (data with multiple variables that measure distinct parts of a whole)

This code and documentation were developed to accompany in-person tutorials for an individual needing to learn just enough R to understand, create, and edit visualizations of their dissertation data. I wrote these notes primarily to serve as reminders of coding topics covered in our tutoring sessions.

NB: R software and packages are regularly updated, so version notes are provided at the end of this document along with instructions on how to roll back to older versions, if necessary.

Load your data

You will need to provide the correct path to your data files.

# Remember to change the file path to your own directory
demodata1 <- read.csv("E:/P_Teaching/DemoSheets/triad_data1.csv")
str(demodata1)
## 'data.frame':    62 obs. of  23 variables:
##  $ ObsID    : int  27 30 2 37 25 5 10 28 4 52 ...
##  $ StartTime: Factor w/ 47 levels "2/3/2016 19:13",..: 10 11 9 43 23 12 47 4 27 38 ...
##  $ EndTime  : Factor w/ 47 levels "2/3/2016 19:13",..: 11 12 10 43 24 13 47 5 28 39 ...
##  $ T1A      : num  9.65 13.07 45.19 42.77 24.14 ...
##  $ T1B      : num  33.2 78.4 42 40.2 17.4 ...
##  $ T1C      : num  57.12 8.53 12.81 16.98 58.42 ...
##  $ T2A      : num  9.6 22.6 46.9 42.9 60.1 ...
##  $ T2B      : num  47.3 58.7 39.4 45.1 23.1 ...
##  $ T2C      : num  43.1 18.8 13.8 12 16.7 ...
##  $ T3A      : num  24.18 16.48 10.8 17.39 9.93 ...
##  $ T3B      : num  54.7 43.8 81.5 70.5 85.4 ...
##  $ T3C      : num  21.1 39.77 7.73 12.11 4.65 ...
##  $ D1X      : num  0.317 0.289 0.247 0.202 0.488 ...
##  $ D1Y      : num  0.683 0.711 0.753 0.798 0.512 ...
##  $ D2X      : num  0.372 0.546 0.82 0.233 0.909 ...
##  $ D2Y      : num  0.6278 0.4543 0.1798 0.7666 0.0915 ...
##  $ D3X      : num  0.665 0.558 0.587 0.699 0.27 ...
##  $ D3Y      : num  0.335 0.442 0.413 0.301 0.73 ...
##  $ F1       : Factor w/ 5 levels "Jupiter","Mars",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ F2       : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ...
##  $ F3       : Factor w/ 2 levels "A","B": 1 2 2 2 2 1 1 2 2 2 ...
##  $ L1XRight : num  0.306 0.351 0.727 0.301 0.724 ...
##  $ L1YTop   : num  0.303 0.5 0.645 0.274 0.772 ...

Evaluate Triad Data by “Binning”

library(ggplot2)
library(ggtern)

# Create visual of tiles and put tile labels at the midpoint of each tile.
# Create a dataframe of the labels and their coordinates
bin_labels = data.frame(T1Bin=c("A", "B", "C", "Mixed"), 
                       T1A=c(0.70,0.15,0.15,0.33), 
                       T1B=c(0.15,0.7,0.15,0.34),
                       T1C=c(0.15,0.15,0.7,0.33))

# Create the ternary plot illustrating the bins using the geom_line and geom_text functions
ggtern(data=demodata1, aes(x=T1A, y=T1B, z=T1C))+
    geom_point()+
    geom_Tline(Tintercept = 0.5, size = 0.5, color = "red")+
    geom_Rline(Rintercept = 0.5, size = 0.5, color = "red")+
    geom_Lline(Lintercept = 0.5, size = 0.5, color = "red")+
    geom_Tline(Tintercept = 0.01, size = 0.5, color = "red")+
    geom_Rline(Rintercept = 0.01, size = 0.5, color = "red")+
    geom_Lline(Lintercept = 0.01, size = 0.5, color = "red")+
    geom_text(data = bin_labels, aes(label = T1Bin, angle = 0), color = 'red',size = 5)

# Assign the responses to their respective bins
t1_bin <- data.frame(T1A=demodata1$T1A, T1B=demodata1$T1B, T1C=demodata1$T1C, D1X=demodata1$D1X, D2X=demodata1$D2X, D3X=demodata1$D3X, T1Bin="Mixed", stringsAsFactors = FALSE)
for(i in 1:nrow(t1_bin)){
    t1_bin$T1Bin[i]<- ifelse(t1_bin$T1A[i] > 50, "A", t1_bin$T1Bin[i])
    t1_bin$T1Bin[i]<- ifelse(t1_bin$T1B[i] > 50, "B", t1_bin$T1Bin[i])
    t1_bin$T1Bin[i]<- ifelse(t1_bin$T1C[i] > 50, "C", t1_bin$T1Bin[i])
}

# Plot the responses on triad again, now colored by assigned bin
T1_tern <- ggtern(data=t1_bin, aes(x=T1A, y=T1B, z=T1C))+
    geom_point(aes(colour=as.factor(T1Bin)))+
    scale_colour_manual(values = c("magenta", "red", "orange", "yellow"), name="Assigned Bin",
                        labels=c("A", "B", "C", "Mixed"))+
    theme_bw()

# Visually explore characteristics on bins using dyads
T1D1_box <- ggplot(data=t1_bin[!is.na(t1_bin$D1X),], aes(x=T1Bin, y=D1X)) +
    geom_boxplot(aes(fill=as.factor(T1Bin))) +
    scale_fill_manual(values = c("magenta", "red", "orange", "yellow"), name="Assigned Bin",
                        labels=c("A", "B", "C", "Mixed"))+
    xlab("Triad 1 Bin") +
    ylab("Dyad 1 Value") +
    guides(fill="none") +
    annotate("text", x =  1:4, y = 0.1, label = c(paste0("N=",sum(t1_bin$T1Bin=="A", na.rm=TRUE)), 
                                                   paste0("N=",sum(t1_bin$T1Bin=="B", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="C", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="Mixed", na.rm=TRUE))))+
    theme_bw()

#Repeat for the D2 dyad
T1D2_box <- ggplot(data=t1_bin[!is.na(t1_bin$D2X),], aes(x=T1Bin, y=D2X)) +
    geom_boxplot(aes(fill=as.factor(T1Bin))) +
    scale_fill_manual(values = c("magenta", "red", "orange", "yellow"), name="Assigned Bin",
                        labels=c("A", "B", "C", "Mixed"))+
    xlab("Triad 1 Bin") +
    ylab("Dyad 2 Value") +
    guides(fill="none") +
    annotate("text", x =  1:4, y = 0.1, label = c(paste0("N=",sum(t1_bin$T1Bin=="A", na.rm=TRUE)), 
                                                   paste0("N=",sum(t1_bin$T1Bin=="B", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="C", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="Mixed", na.rm=TRUE))))+
    theme_bw()

#Repeat for the D3 dyad
T1D3_box <- ggplot(data=t1_bin[!is.na(t1_bin$D3X),], aes(x=T1Bin, y=D3X)) +
    geom_boxplot(aes(fill=as.factor(T1Bin))) +
    scale_fill_manual(values = c("magenta", "red", "orange", "yellow"), name="Assigned Bin",
                        labels=c("A", "B", "C", "Mixed"))+
    xlab("Triad 1 Bin") +
    ylab("Dyad 2 Value") +
    guides(fill="none") +
    annotate("text", x =  1:4, y = 0.1, label = c(paste0("N=",sum(t1_bin$T1Bin=="A", na.rm=TRUE)), 
                                                   paste0("N=",sum(t1_bin$T1Bin=="B", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="C", na.rm=TRUE)),
                                                   paste0("N=",sum(t1_bin$T1Bin=="Mixed", na.rm=TRUE))))+
    theme_bw()

# Plot all the figures together using grid arrange
grid.arrange(T1_tern, T1D1_box, T1D2_box, T1D3_box, ncol=2, nrow=2)

Session and Package Information

I created and tested these examples with:

If you need to install older versions of ggplot2 and ggtern enter these commands (substitute the version numbers you are seeking):

After installation, you should restart R Studio.

Contact Information

For more information about this R script and associated data support consulting services, contact Dr. Ashton Drew.

alt text