Skip to content

rthor

pre-commit Tests status Linting status Documentation status License

rthor is a Python implementation of RTHOR (Randomization Test of Hypothesized Order Relations), a statistical test for circumplex and circular models in correlation matrices.

Features

  • Exact Parity with RTHORR: Produces numerically identical results to the original RTHORR package
  • Multiple Input Formats: Works with files, pandas DataFrames, or numpy arrays
  • Flexible Analysis: Test single matrices or compare multiple matrices pairwise
  • Fast Performance: Vectorized operations using NumPy for efficient computation

Quick Start

import rthor

# Test from correlation matrix file
df = rthor.test(
    "correlations.txt",
    order="circular6",
    n_matrices=3,
    n_variables=6,
    labels=["Sample 1", "Sample 2", "Sample 3"]
)

# View results (returns a pandas DataFrame)
print(df)
matrix predictions agreements ties ci p_value label n_permutations n_variables
0 1 72 59 1 0.652778 0.016667 Sample 1 720 6
1 2 72 53 1 0.486111 0.033333 Sample 2 720 6
2 3 72 56 3 0.597222 0.016667 Sample 3 720 6
df[df['ci'] > 0.5]  # Filter results
matrix predictions agreements ties ci p_value label n_permutations n_variables
0 1 72 59 1 0.652778 0.016667 Sample 1 720 6
2 3 72 56 3 0.597222 0.016667 Sample 3 720 6
# Or print formatted results
rthor.print_results(df)
                                   RTHOR Test Results                                    
              3 matrices • 6 variables • 72 predictions • 720 permutations               
╭──────────────┬────┬───────┬────────────────┬──────────────┬─────────────┬─────────────╮
│ Matrix               CI  Interpretation  Significance    Satisfied     Violated │
├──────────────┼────┼───────┼────────────────┼──────────────┼─────────────┼─────────────┤
│ [1] Sample 1  0.653 │ Good fit       │   p<.05 * 59/72 (82%)  12/72 (17%) │
│ [2] Sample 2  0.486 │ Moderate fit   │   p<.05 * 53/72 (74%)  18/72 (25%) │
│ [3] Sample 3  0.597 │ Good fit       │   p<.05 * 56/72 (78%)  13/72 (18%) │
╰──────────────┴────┴───────┴────────────────┴──────────────┴─────────────┴─────────────╯
                ℹ️  Higher CI values indicate better fit (range: -1 to +1)                

Test from DataFrames

df = rthor.test(
[df1, df2, df3],
order="circular6",
labels=["Group A", "Group B", "Group C"],
print_results=True # Print formatted results automatically
)
                                   RTHOR Test Results                                    
              3 matrices • 6 variables • 72 predictions • 720 permutations               
╭─────────────┬────┬───────┬────────────────┬──────────────┬──────────────┬─────────────╮
│ Matrix              CI  Interpretation  Significance     Satisfied     Violated │
├─────────────┼────┼───────┼────────────────┼──────────────┼──────────────┼─────────────┤
│ [1] Group A  1.000 │ Excellent fit  │   p<.05 * 72/72 (100%)    0/72 (0%) │
│ [2] Group B  0.583 │ Good fit       │   p<.05 *  57/72 (79%)  15/72 (21%) │
│ [3] Group C  0.056 │ Minimal fit    │   p=0.433  38/72 (53%)  34/72 (47%) │
╰─────────────┴────┴───────┴────────────────┴──────────────┴──────────────┴─────────────╯
                ℹ️  Higher CI values indicate better fit (range: -1 to +1)                

Compare multiple matrices

individual, pairwise = rthor.compare(
[df1, df2, df3],
order="circular6",
print_results=True
)
                                RTHOR Matrix Comparison                                
             3 matrices • 6 variables • 72 predictions • 720 permutations              
╭────────────┬────┬────────┬─────────────────┬──────────────┬───────┬────────┬────────╮
│ Comparison          CI  Result           Significance   Both  Only 1  Only 2 │
├────────────┼────┼────────┼─────────────────┼──────────────┼───────┼────────┼────────┤
│ Matrix 1     1.000 │ Excellent fit   │   p<.05 * 72/72 │
│ Matrix 2     0.583 │ Good fit        │   p<.05 * 57/72 │
│ Matrix 3     0.056 │ Minimal fit     │   p=0.433 38/72 │
├────────────┼────┼────────┼─────────────────┼──────────────┼───────┼────────┼────────┤
│ 1 vs 2      -0.208 │ Matrix 1 better │   p=0.933    57      15       0 │
│ 1 vs 3      -0.472 │ Matrix 1 better │   p=0.983    38      34       0 │
│ 2 vs 3      -0.264 │ Matrix 2 better │   p=0.967    37      20       1 │
╰────────────┴────┴────────┴─────────────────┴──────────────┴───────┴────────┴────────╯
   Info: Positive CI means matrix 2 fits better, negative means matrix 1 fits better   

Installation

See Installation Instructions for more details.

pip install rthor

What is RTHOR?

RTHOR (Randomization Test of Hypothesized Order Relations) is a statistical method for testing whether correlation matrices conform to a hypothesized ordering of variables 12. This is particularly useful for:

  • Circumplex Models: Variables arranged in a circular pattern (e.g., interpersonal behavior, emotions)
  • Circular Structures: Testing theoretical predictions about variable ordering
  • Correlation Patterns: Validating expected patterns in correlation matrices

The test uses a randomization approach to compute p-values, comparing the observed Correspondence Index (CI) with values from permuted data. CI ranges from -1 (perfect disagreement) to +1 (perfect agreement).

Key Functions

rthor.test()

Test whether correlation matrices conform to a hypothesized ordering.

Parameters:

  • data: Input data (file path, list of DataFrames, or numpy array)
  • order: Hypothesized ordering ("circular6", "circular8", or custom list)
  • labels: Optional descriptive labels for matrices
  • n_matrices: Number of matrices (required for file input)
  • n_variables: Number of variables (required for file input)
  • print_results: If True, print formatted results table

Returns: pandas DataFrame with columns: matrix, predictions, agreements, ties, ci, p_value, label, n_permutations, n_variables

rthor.compare()

Compare multiple correlation matrices pairwise to determine which fits the hypothesis better.

Parameters: Same as rthor.test() but requires at least 2 matrices

Returns: Tuple of two pandas DataFrames: (individual_results, pairwise_comparisons)

Documentation

Full documentation is available at https://drandrewmitchell.com/rthor

Validation Against Original Paper

The implementation has been validated against the original Hubert & Arabie (1987) 3 paper. See docs/examples/paper-validation.py for a detailed demonstration that replicates Table 1 from the paper and confirms exact agreement with the expected results:

  • ✓ 72 predictions, 61 agreements, 11 violations
  • ✓ p-value = 0.0167 (12/720)
  • ✓ CI = 0.694

Testing

Run tests across all supported Python versions:

tox

Run tests in current environment:

pytest tests

Run tests with coverage:

pytest --cov --cov-report=xml

Development

This project uses:

  • uv for dependency management
  • ruff for linting and formatting
  • pytest for testing
  • mkdocs with Material theme for documentation
  • pre-commit hooks (via prek) for code quality

Install development dependencies:

uv sync --all-extras

Run pre-commit hooks:

uv run prek run -a

Build documentation:

uv run mkdocs serve

Project Team

Andrew Mitchell (andrew.mitchell.research@gmail.com)

Research Software Engineering Contact

Centre for Advanced Research Computing, University College London (arc.collaborations@ucl.ac.uk)

Citation

If you use rthor in your research, please cite both this package and the original method paper:

rthor (Python implementation):

@software{Mitchell2025rthor,
  author  = {Mitchell, Andrew},
  license = {MIT},
  title   = {{rthor: Python implementation of RTHOR (Randomization test of hypothesized order relations)}},
  url     = {https://github.com/MitchellAcoustics/rthor}
}

Original RTHOR method:

@article{Hubert1987Evaluating,
  author  = {Hubert, Lawrence and Arabie, Phipps},
  year    = {1987},
  month   = {07},
  pages   = {172-178},
  title   = {Evaluating Order Hypotheses Within Proximity Matrices},
  volume  = {102},
  journal = {Psychological Bulletin},
  doi     = {10.1037/0033-2909.102.1.172}
}

R RTHORR package:

@software{Tracey2025RTHORR,
  title  = {RTHORR: randomization test of hypothesized order relations (RTHOR) and
            comparisons},
  author = {Terence J. G. Tracey and Michael L. Morris},
  year   = {2025},
  note   = {R package version 0.1.3, commit c3edb36287c77733ec0a23236b478cc53c1cac0f},
  url    = {https://github.com/michaellynnmorris/RTHORR}
}

License

MIT License. See LICENSE.md for details.

Acknowledgments

This project is developed in collaboration with the Centre for Advanced Research Computing, University College London.

rthor is a Python port of the R package RTHORR by Michael B. Gurtman. The implementation maintains exact numerical parity with the original R version while providing a Pythonic interface and improved performance through vectorization.


  1. Terence J. G. Tracey and Michael L. Morris. Rthorr: randomization test of hypothesized order relations (rthor) and comparisons. 2025. R package version 0.1.3, commit c3edb36287c77733ec0a23236b478cc53c1cac0f. URL: https://github.com/michaellynnmorris/RTHORR

  2. Terence J. G. Tracey. Randall: a microsoft fortran program for a randomization test of hypothesized order relations. Educational and Psychological Measurement, 57(1):164–168, February 1997. doi:10.1177/0013164497057001012

  3. Lawrence Hubert and Phipps Arabie. Evaluating order hypotheses within proximity matrices. Psychological Bulletin, 102:172–178, 07 1987. doi:10.1037/0033-2909.102.1.172