Skip to main 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 [@Tracey2025RTHORR;@Tracey1997RANDALL]. 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) [@Hubert1987Evaluating] 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.

Metadata

Release files for rthor 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rthor 0.2.1
File Size Uploaded
rthor-0.2.1.tar.gz 46.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rthor 0.2.1
File Interpreter ABI Platform
rthor-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 71.8 kB

Release files / rthor-0.2.1.tar.gz

Download URL rthor-0.2.1.tar.gz
Size 46.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c8bcf87a036fd148574d45b5f6c953d1750a5d2cc8a66f0c8229f966a196e74f
BLAKE2b-256 checksum
How to use checksums
1ae7a9a70fb1519305cccd61cacbaac169a6493468b6707a7b8c60890df963f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.0

Release files / rthor-0.2.1-py3-none-any.whl

Download URL rthor-0.2.1-py3-none-any.whl
Size 25.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3a223e3c8050fe7c6e2a88a0367beccc65f1bd77dd9fe96895bf557348220b34
BLAKE2b-256 checksum
How to use checksums
ce385f22a877b3f5eeb402cfc6633e6946881af126f2e477569b3abb43d4e399
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.0

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page