opa

An R package for ordinal pattern analysis.

Installation

opa can be installed from CRAN with:

install.packages("opa")

You can install the development version of opa from GitHub with:

# install.packages("remotes")
remotes::install_github("timbeechey/opa")

Citation

To cite opa in your work you can use the output of:

citation(package = "opa")

Background

opa is an implementation of methods described in publications including Thorngate (1987) and Grice et al. (2015). Thorngate (1987) attributes the original idea to:

Parsons, D. (1975). The directory of tunes and musical themes. S. Brown.

How ordinal pattern analysis works

Ordinal pattern analysis is similar to Kendall’s Tau. Whereas Kendall’s tau is a measure of similarity between two data sets in terms of rank ordering, ordinal pattern analysis is intended to quantify the match between a hypothesis and patterns of individual-level data across conditions or measurement instances.

Ordinal pattern analysis works by comparing the relative ordering of pairs of observations and computing whether those pairwise relations are matched by a hypothesis. Each pairwise ordered relation is classified as an increases, a decrease, or as no change. These classifications are encoded as 1, -1 and 0, respectively. For example, a hypothesis of a monotonic increase in a response variable across four experimental conditions can be specified as:

h <- c(1, 2, 3, 4)

Note that the absolute values are not important, only their relative ordering. The hypothesis h encodes six pairwise relations, all increases: 1 1 1 1 1 1.

A row of individual data representing measurements across four conditions, such as:

dat <- c(65.3, 68.8, 67.0, 73.1)

encodes six ordered pairwise relations 1 1 1 -1 1 1. The percentage of orderings which are correctly classified by the hypothesis (PCC) is the main quantity of interest in ordinal pattern analysis. Comparing h and dat, the PCC is 5/6 = 0.833 or 83.3%. A hypothesis which generates a greater PCC is preferred over a hypothesis which generates a lower PCC for given data.

It is also possible to calculate a chance-value for a PCC which is equal to the chance that a PCC at least as great as the PCC of the observed data could occur as a result of a random re-ordering of the data. Chance values can be computed using either a permutation test or a randomization test.

Using opa

library(opa)

A hypothesized relative ordering of a response variable across conditions is specified with a numeric vector:

h <- c(1, 2, 4, 3)

The hypothesis can be plotted with the plot_hypothesis() function:

plot_hypothesis(h)

Data should be in wide format with one column per measurement condition and one row per individual:

set.seed(123)

dat <- data.frame(t1 = rnorm(20, mean = 12, sd = 2),
                  t2 = rnorm(20, mean = 15, sd = 2),
                  t3 = rnorm(20, mean = 20, sd = 2),
                  t4 = rnorm(20, mean = 17, sd = 2))
                  
round(dat, 2)
#>       t1    t2    t3    t4
#> 1  10.88 12.86 18.61 17.76
#> 2  11.54 14.56 19.58 16.00
#> 3  15.12 12.95 17.47 16.33
#> 4  12.14 13.54 24.34 14.96
#> 5  12.26 13.75 22.42 14.86
#> 6  15.43 11.63 17.75 17.61
#> 7  12.92 16.68 19.19 17.90
#> 8   9.47 15.31 19.07 17.11
#> 9  10.63 12.72 21.56 18.84
#> 10 11.11 17.51 19.83 21.10
#> 11 14.45 15.85 20.51 16.02
#> 12 12.72 14.41 19.94 12.38
#> 13 12.80 16.79 19.91 19.01
#> 14 12.22 16.76 22.74 15.58
#> 15 10.89 16.64 19.55 15.62
#> 16 15.57 16.38 23.03 19.05
#> 17 13.00 16.11 16.90 16.43
#> 18  8.07 14.88 21.17 14.56
#> 19 13.40 14.39 20.25 17.36
#> 20 11.05 14.24 20.43 16.72

An ordinal pattern analysis model to consider how the hypothesis h matches each individual pattern of results in dat can be fitted using:

opamod <- opa(dat, h, cval_method = "exact")

Specifying cval_method = "exact" computes chance values using a permutation test which considers every possible ordering of the data to determine the exact chance of a PCC at least as high as the PCC of the observed data. Specifying instead cval_method = "stochastic" computes chance values using a randomisation. The number of random orderings to consider can be specified with the nreps argument which defaults to 1000.

A summary of the model output can be viewed using:

summary(opamod)
#> Ordinal Pattern Analysis of 4 observations for 20 individuals in 1 group 
#> 
#> Between subjects results:
#>          PCC cval
#> pooled 93.33  0.1
#> 
#> Within subjects results:
#>       PCC cval
#> 1  100.00 0.04
#> 2  100.00 0.04
#> 3   83.33 0.17
#> 4  100.00 0.04
#> 5  100.00 0.04
#> 6   83.33 0.17
#> 7  100.00 0.04
#> 8  100.00 0.04
#> 9  100.00 0.04
#> 10  83.33 0.17
#> 11 100.00 0.04
#> 12  66.67 0.38
#> 13 100.00 0.04
#> 14  83.33 0.17
#> 15  83.33 0.17
#> 16 100.00 0.04
#> 17 100.00 0.04
#> 18  83.33 0.17
#> 19 100.00 0.04
#> 20 100.00 0.04
#> 
#> PCCs were calculated for pairwise ordinal relationships using a difference threshold of 0.
#> Chance-values were calculated using the exact method.

Individual-level model output can be plotted using:

plot(opamod)

To aid in visual interpretation, individual PCCs and c-values can also be plotted relative to user-specified thresholds:

pcc_plot(opamod, threshold = 90)
cval_plot(opamod, threshold = 0.1)

Pairwise comparison of measurement conditions

Pairwise comparisons of measurement conditions can be calculated by applying the compare_conditions() function to an opafit object produced by a call to opa():

condition_comparisons <- compare_conditions(opamod)

condition_comparisons$pccs
#>     1   2  3 4
#> 1   -   -  - -
#> 2  90   -  - -
#> 3 100 100  - -
#> 4  95  80 95 -
condition_comparisons$cvals
#>       1   2     3 4
#> 1     -   -     - -
#> 2  0.55   -     - -
#> 3   0.5 0.5     - -
#> 4 0.525 0.6 0.525 -

Multiple groups

If the data consist of multiple groups a categorical grouping variable can be passed with the group keyword to produce results for each group within the data, in addition to individual results.

dat$group <- rep(c("A", "B", "C", "D"), 5)
dat$group <- factor(dat$group, levels = c("A", "B", "C", "D"))

opamod2 <- opa(dat[, 1:4], h, group = dat$group, cval_method = "exact")

The summary output displays results organised by group.

summary(opamod2)
#> Ordinal Pattern Analysis of 4 observations for 20 individuals in 4 groups 
#> 
#> Between subjects results:
#>      PCC cval
#> A 100.00 0.04
#> B  86.67 0.14
#> C  93.33 0.09
#> D  93.33 0.11
#> 
#> Within subjects results:
#>   Individual    PCC cval
#> A          1 100.00 0.04
#> A          5 100.00 0.04
#> A          9 100.00 0.04
#> A         13 100.00 0.04
#> A         17 100.00 0.04
#> B          2 100.00 0.04
#> B          6  83.33 0.17
#> B         10  83.33 0.17
#> B         14  83.33 0.17
#> B         18  83.33 0.17
#> C          3  83.33 0.17
#> C          7 100.00 0.04
#> C         11 100.00 0.04
#> C         15  83.33 0.17
#> C         19 100.00 0.04
#> D          4 100.00 0.04
#> D          8 100.00 0.04
#> D         12  66.67 0.38
#> D         16 100.00 0.04
#> D         20 100.00 0.04
#> 
#> PCCs were calculated for pairwise ordinal relationships using a difference threshold of 0.
#> Chance-values were calculated using the exact method.

Similarly, plotting the output shows individual PCCs and c-values by group.

plot(opamod2)

Acknowledgements

Development of opa was supported by a Medical Research Foundation Fellowship (MRF-049-0004-F-BEEC-C0899).