Skip to main content

Python implementation of RTHOR (Randomization test of hypothesized order relations)

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rthor-0.2.1.tar.gz (46.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rthor-0.2.1-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file rthor-0.2.1.tar.gz.

File metadata

  • Download URL: rthor-0.2.1.tar.gz
  • Upload date:
  • Size: 46.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.0

File hashes

Hashes for rthor-0.2.1.tar.gz
Algorithm Hash digest
SHA256 c8bcf87a036fd148574d45b5f6c953d1750a5d2cc8a66f0c8229f966a196e74f
MD5 274332875653164b983e76768bff81da
BLAKE2b-256 1ae7a9a70fb1519305cccd61cacbaac169a6493468b6707a7b8c60890df963f9

See more details on using hashes here.

File details

Details for the file rthor-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: rthor-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.0

File hashes

Hashes for rthor-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3a223e3c8050fe7c6e2a88a0367beccc65f1bd77dd9fe96895bf557348220b34
MD5 4f34bfbf65cb0e3e79624a18b3fc09b7
BLAKE2b-256 ce385f22a877b3f5eeb402cfc6633e6946881af126f2e477569b3abb43d4e399

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page