Skip to main content

Monte Carlo Power Analysis for Statistical Models

Project description

MCPower

Simple Monte Carlo power analysis for complex models. Find the sample size you need or check if your study has enough power - even with complex models that traditional power analysis can't handle.

Why MCPower?

Traditional power analysis breaks down with interactions, correlated predictors, or non-normal data. MCPower uses simulation instead of formulas - it generates thousands of datasets exactly like yours, then sees how often your analysis finds real effects.

Works with complexity: Interactions, correlations, any distribution
R-style formulas: outcome = treatment + covariate + treatment*covariate
Two simple commands: Find sample size or check power
Scenario analysis: Test robustness under realistic conditions
Minimal math required: Just specify your model and effects

Get Started in 2 Minutes

Install

pip install git+https://github.com/pawlenartowicz/MCPower

Update to the latest version (every few days).

pip install --upgrade git+https://github.com/pawlenartowicz/MCPower

Your First Power Analysis

# 0. First initialization could take a few seconds, due to compilation (package is not distributed yet with compiled files)
import mcpower

# 1. Define your model (just like R)
model = mcpower.LinearRegression("satisfaction = treatment + motivation")

# 2. Set effect sizes (how big you expect effects to be)
model.set_effects("treatment=0.5, motivation=0.3")

# 3. Change the treatment to "binary" (people receive treatment or not).
model.set_variable_type("treatment=binary")

# 4. Find the sample size you need
model.find_sample_size(target_test="treatment", from_size=50, to_size=200)

Output: "You need N=75 for 80% power to detect the treatment effect"

That's it! 🎉

🎯 Scenario Analysis: Test Your Assumptions

Real studies rarely match perfect assumptions. MCPower's scenario analysis tests how robust your power calculations are under realistic conditions.

# Test robustness with scenario analysis
model.find_sample_size(
    target_test="treatment", 
    from_size=50, to_size=300,
    scenarios=True  # 🔥 The magic happens here
)

Output:

SCENARIO SUMMARY
================================================================================

Uncorrected Sample Sizes:
Test                                     Optimistic   Realistic    Doomer      
-------------------------------------------------------------------------------
treatment                                75           85           100         
================================================================================

What each scenario means:

  • Optimistic: Your ideal conditions (original settings)
  • Realistic: Moderate real-world complications (small effect variations, mild assumption violations)
  • Doomer: Conservative estimate (larger effect variations, stronger assumption violations)

💡 Pro tip: Use the Realistic scenario for planning. If Doomer is acceptable, you're really safe!

Understanding Effect Sizes

Effect sizes tell you how much the outcome changes when predictors change.

  • Effect size = 0.5 means the outcome increases by 0.5 standard deviations when:
    • Continuous variables: Predictor increases by 1 standard deviation
    • Binary variables: Predictor changes from 0 to 1 (e.g., control → treatment)

Practical examples:

model.set_effects("treatment=0.5, age=0.3, income=0.2")
  • treatment=0.5: Treatment increases outcome by 0.5 SD (medium-large effect)
  • age=0.3: Each 1 SD increase in age → 0.3 SD increase in outcome
  • income=0.2: Each 1 SD increase in income → 0.2 SD increase in outcome

Effect size guidelines:

  • 0.1 = Small effect (detectable but modest)
  • 0.25 = Medium effect (clearly noticeable)
  • 0.4 = Large effect (substantial impact)

Effect size guidelines (binary variables):

  • 0.2 = Small effect (detectable but modest)
  • 0.5 = Medium effect (clearly noticeable)
  • 0.8 = Large effect (substantial impact)

Your uploaded data is automatically standardized (mean=0, SD=1) so effect sizes work the same way whether you use synthetic or real data.

Copy-Paste Examples for Common Studies

Randomized Controlled Trial

import mcpower

# RCT with treatment + control variables
model = mcpower.LinearRegression("outcome = treatment + age + baseline_score")
model.set_effects("treatment=0.6, age=0.2, baseline_score=0.8")
model.set_variable_type("treatment=binary")  # 0/1 treatment

# Find sample size for treatment effect with scenario analysis
model.find_sample_size(target_test="treatment", from_size=100, to_size=500, 
                      by=50, scenarios=True)

A/B Test with Interaction

import mcpower

# Test if treatment effect depends on user type
model = mcpower.LinearRegression("conversion = treatment + user_type + treatment*user_type")
model.set_effects("treatment=0.4, user_type=0.3, treatment:user_type=0.5")
model.set_variable_type("treatment=binary, user_type=binary")

# Check power robustness for the interaction
model.find_power(sample_size=400, target_test="treatment:user_type", scenarios=True)

Survey with Correlated Predictors

import mcpower

# Predictors are often correlated in real data
model = mcpower.LinearRegression("wellbeing = income + education + social_support")
model.set_effects("income=0.4, education=0.3, social_support=0.6")
model.set_correlations("corr(income, education)=0.5, corr(income, social_support)=0.3")

# Find sample size for any effect
model.find_sample_size(target_test="all", from_size=200, to_size=800, 
                      by=100, scenarios=True)

Customize for Your Study

Different Variable Types

# Binary (0/1), skewed, or other distributions
model.set_variable_type("treatment=binary, income=right_skewed, age=normal")

# Binary with custom proportions (30% get treatment)
model.set_variable_type("treatment=(binary,0.3)")

Your Own Data (be careful, not yet well tested)

import pandas as pd

# Use your pilot data for realistic simulations
df = pd.read_csv('examples/cars.csv')
model.upload_own_data(df)  # Automatically preserves correlations

Multiple Testing

# Testing multiple effects? Control false positives
model.find_power(
    sample_size=200, 
    target_test="treatment,covariate,treatment:covariate",
    correction="Benjamini-Hochberg",
    scenarios=True  # Test robustness too!
)

Test the single violation of assumptions.

# Customize how much "messiness" to add in scenarios
model.set_heterogeneity(0.2)        # Effect sizes vary between people
model.set_heteroskedasticity(0.15)  # Violation of equal variance assumption

# Then run scenario analysis
model.find_sample_size(target_test="treatment", scenarios=False)

More precision

# To make a more precise estimation, consider increasing the number of simulations.
model.set_simulations(10000)

# MCPower is already heavily optimized, but there is old code that allows for parallelization. Use it to speed up your largest simulations.
model.set_parallel(True)

Quick Reference

Want to... Use this
Find required sample size model.find_sample_size(target_test="effect_name")
Check power for specific N model.find_power(sample_size=150, target_test="effect_name")
Test robustness Add scenarios=True to either method
Test overall model target_test="overall"
Test multiple effects target_test="effect1, effect2" or "all"
Binary variables model.set_variable_type("var=binary")
Correlated predictors model.set_correlations("corr(var1, var2)=0.4")
Multiple testing correction Add correction="FDR", or "Holm" pr "Bonferroni"

When to Use MCPower

✅ Use MCPower when you have:

  • Interaction terms (treatment*covariate)
  • Binary or non-normal variables
  • Correlated predictors
  • Multiple effects to test
  • Need to test assumption robustness
  • Complex models where traditional power analysis fails

✅ Use Scenario Analysis when:

  • Planning important studies (grants, dissertations)
  • Working with messy real-world data
  • Effect sizes are uncertain
  • Want conservative sample size estimates
  • Stakeholders need confidence in your numbers

❌ Use traditional power analysis for:

  • For models that are not yet implemented
  • When all assumptions are clearly met

What Makes Scenarios Different? (Be careful, unvalidated, preliminary scenarios)

Traditional power analysis assumes perfect conditions. MCPower's scenarios add realistic "messiness":

Scenario What's Different When to Use
Optimistic Your exact settings Best-case planning
Realistic Mild effect variations, small assumption violations Recommended for most studies
Doomer Larger effect variations, stronger assumption violations Conservative/worst-case planning

Behind the scenes, scenarios randomly vary:

  • Effect sizes between participants
  • Correlation strengths
  • Variable distributions
  • Assumption violations

This gives you a range of realistic outcomes instead of a single optimistic estimate. ⚠️ Important: Scenario analysis and uploaded data features are experimental. Use with caution for critical decisions.

📚 Advanced Features (Click to expand)

Advanced Options

All Variable Types

model.set_variable_type("""
    treatment=binary,           # 0/1 with 50% split
    ses=(binary,0.3),          # 0/1 with 30% split  
    age=normal,                # Standard normal (default)
    income=right_skewed,       # Positively skewed
    depression=left_skewed,    # Negatively skewed
    response_time=high_kurtosis, # Heavy-tailed
    rating=uniform             # Uniform distribution
""")

Complex Correlation Structures

import numpy as np

# Full correlation matrix for 3 variables
corr_matrix = np.array([
    [1.0, 0.4, 0.6],    # Variable 1 with others
    [0.4, 1.0, 0.2],    # Variable 2 with others
    [0.6, 0.2, 1.0]     # Variable 3 with others
])
model.set_correlations(corr_matrix)

Performance Tuning

# Adjust for your needs
model.set_power(90)           # Target 90% power instead of 80%
model.set_alpha(0.01)         # Stricter significance (p < 0.01)
model.set_simulations(10000)  # High precision (slower)

Formula Syntax

# These are equivalent:
"y = x1 + x2 + x1*x2"        # Assignment style
"y ~ x1 + x2 + x1*x2"        # R-style formula  
"x1 + x2 + x1*x2"            # Predictors only

# Interactions:
"x1*x2"         # Main effects + interaction (x1 + x2 + x1:x2)
"x1:x2"         # Interaction only
"x1*x2*x3"      # All main effects + all interactions

Correlation Syntax

# String format (recommended)
model.set_correlations("corr(x1, x2)=0.3, corr(x1, x3)=-0.2")

# Shorthand format  
model.set_correlations("(x1, x2)=0.3, (x1, x3)=-0.2")

Requirements

  • Python ≥ 3.7
  • NumPy, SciPy, scikit-learn, matplotlib
  • joblib (optional, for parallel processing)

Need Help?

Aim for future (waiting for suggestions)

  • ✅ Linear Regression
  • 🚧 Logistic Regression (coming soon)
  • 🚧 Tweaking scenarios, robustness analysis (coming soon)
  • 🚧 Guide about methods, corrections (coming soon)
  • 🚧 ANOVA (and factor as variables) (coming soon)
  • 📋 Mixed Effects Models
  • 📋 2 groups comparision with alternative tests
  • 📋 Robust regression methods

License & Citation

GPL v3. If you use MCPower in research, please cite:

@software{mcpower2025,
  author = {Pawel Lenartowicz},
  title = {MCPower: Monte Carlo Power Analysis for Statistical Models},
  year = {2025},
  url = {https://github.com/pawlenartowicz/MCPower}
}

🚀 Ready to start? Copy one of the examples above and adapt it to your study!

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

mcpower-0.3.0.tar.gz (57.9 kB view details)

Uploaded Source

Built Distributions

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

mcpower-0.3.0-cp312-cp312-win_amd64.whl (420.3 kB view details)

Uploaded CPython 3.12Windows x86-64

mcpower-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

mcpower-0.3.0-cp312-cp312-macosx_11_0_arm64.whl (585.3 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

mcpower-0.3.0-cp311-cp311-win_amd64.whl (299.1 kB view details)

Uploaded CPython 3.11Windows x86-64

mcpower-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

mcpower-0.3.0-cp311-cp311-macosx_11_0_arm64.whl (409.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

mcpower-0.3.0-cp310-cp310-win_amd64.whl (178.0 kB view details)

Uploaded CPython 3.10Windows x86-64

mcpower-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (611.0 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

mcpower-0.3.0-cp310-cp310-macosx_11_0_arm64.whl (232.6 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

File details

Details for the file mcpower-0.3.0.tar.gz.

File metadata

  • Download URL: mcpower-0.3.0.tar.gz
  • Upload date:
  • Size: 57.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for mcpower-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1b7ae9c7088f33f48277d5938b0c07e333fd5f49a20070c28046aca39151296c
MD5 0f1384870972bca7add45542cc4282a1
BLAKE2b-256 72fffc58613a003c52fa7601031e0fef07202b09a9ec8d639284c2f907248b59

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: mcpower-0.3.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 420.3 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for mcpower-0.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f0152b3dcc932dc093485b23e8c4b8f2843ded85c4d9d692bd79514914325942
MD5 7297ea5b37de0e77c886d011244b3ce9
BLAKE2b-256 b164f8e0cb44581158c4fde0791e0edb8da9cb96c1ef87f73f7231cf5adba55f

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f67097b88e35906894c9122ded899250fb7d0c563ec290af46b862649c837bfa
MD5 bb4ac3feba6983f854ab771984f088f3
BLAKE2b-256 bda93b2c678cde32eb288f6d9e3a7012d8acd4e74e3216a442d442896ae0887e

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ccdf2d2ff82a40c2931704c24ee28bfe37389df3626ed92ac696a20bf716edc8
MD5 813ad692c92993034c0c826a33ac6151
BLAKE2b-256 b91bfd545834f8b67a6b60608bf35f4ea660e940eb6c4852daf58e5e613afedf

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: mcpower-0.3.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 299.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for mcpower-0.3.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 f1f24ca00624aa854ad5f54f015552b0e46c6887c441859822389a44f73de2f6
MD5 db6e8f6beddc9e2a8c0a452aad37c5ed
BLAKE2b-256 e9b231b29c0ec5db623359ee44d49c5de866f29f7bf01436c7d2e59036aca150

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4de66f920b6b49983f79b4abf2c6368e906fd23edc23513bb01a89c9b23f03b8
MD5 0f7c8b8a8efdc893b454c0683de318ef
BLAKE2b-256 81f24c647d16b01fb8db729f960cd117aaf6a6ca343fe7d28ab481d387e3ceb1

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 896ab4d550979ffa7bd7bde13237bc95dabbea9c0cde3b756bc570c1bdf1a97b
MD5 adb6c2a585316c191abbf5db158da9ef
BLAKE2b-256 470351a22bab1beb26dcdb12a0048bcf407a3d3daeee9e3af0ec5cbbaffe4c8c

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: mcpower-0.3.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 178.0 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for mcpower-0.3.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 d018af75ff53a97f57cdccd6c32bf894e50689c1b93544d45f5967a677daf14e
MD5 4f6e8445fa4e9b9d512c78e4b5f3a86b
BLAKE2b-256 41fadff5cbe98e494ced87cecb5a0ab83640727aa46bfdb4602ac97b764dc24a

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 61723f8bdff15462214aeb252dd0fa0b20e963c45ac598658025d730eafab851
MD5 ca673363f8ecce8ba9c8ec268dd5e6d2
BLAKE2b-256 6f679f519fa6bcd66e96f58f1327cfc670feae344f1258ce92e1bd18573cf00e

See more details on using hashes here.

File details

Details for the file mcpower-0.3.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mcpower-0.3.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ff359608a3fb86a198bbda35d0e5c3f6f4b0330c72f07bb76753fbf9c9fae6b0
MD5 04924be675617d465e5cc58c9d65646e
BLAKE2b-256 e31570e124e5d50ecbca27b285b068945f5eae5e9514c4ac5c478f049781ada0

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