Skill

Generate Statistical Analysis Scripts in Python and R

Writes reproducible Python/R statistical analyses - assumption checking, automatic test selection, effect sizes, power analysis, APA reporting.

Works with github

Maintainer of this project? Claim this page to edit the listing.


79
Spark score
out of 100
Updated 10 days ago
Version 1.0.0
Models

Add to Favorites

Why it matters

Automate complex statistical analyses by generating robust and reproducible scripts in Python and R. Ensure accurate hypothesis testing, effect size reporting, and clear interpretation of results for data-driven decision-making.

Outcomes

What it gets done

01

Generate Python and R code for descriptive statistics.

02

Implement assumption checking for statistical tests (normality, homogeneity of variance).

03

Select and execute appropriate statistical tests (t-tests, Mann-Whitney U).

04

Create publication-ready visualizations with statistical annotations.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/vb-statistical-analysis-script | bash

Overview

Statistical Analysis Script Expert

A skill for writing reproducible statistical analyses in Python and R - automatic assumption checking (normality, variance), test selection between parametric and non-parametric tests, Cohen's d effect sizes with interpretation, power/sample-size analysis, and APA-style reporting. Use it when running a statistical group comparison in Python or R that needs correct assumption-based test selection, effect size reporting, and a reproducible, publication-ready write-up.

What it does

This skill writes robust, reproducible statistical analyses in Python and R, grounded in core principles: always check assumptions (normality, homogeneity of variance, independence) before applying a test, report effect sizes alongside p-values for practical significance, apply corrections for multiple comparisons, provide and interpret confidence intervals in context, document methodology, and handle missing data transparently.

In Python it builds a StatisticalAnalysis class (using pandas, numpy, scipy.stats, statsmodels) with methods for descriptive statistics (including skewness and kurtosis), normality checking via both Shapiro-Wilk and D'Agostino's tests, and automatic group comparison that selects the right test based on assumption checks: an independent t-test (with Levene's test deciding equal vs. unequal variance) when both groups are normal, or a Mann-Whitney U test with rank-biserial correlation as effect size when they're not. The R template (tidyverse, psych, effsize, car, ggplot2, corrplot) mirrors this logic - descriptive stats grouped by the independent variable, Shapiro and Levene assumption tests, then branching to an equal-variance t-test, Welch's t-test, or a Wilcox/Mann-Whitney test with Cohen's d or Cliff's delta as the effect size.

def interpret_effect_size(d, test_type='cohens_d'):
    """Provide interpretation of effect sizes"""
    if test_type == 'cohens_d':
        if abs(d) < 0.2:
            return "negligible"
        elif abs(d) < 0.5:
            return "small"
        elif abs(d) < 0.8:
            return "medium"
        else:
            return "large"

For visualization it builds publication-ready, statistically annotated plots - a box plot with individual points and a p-value/effect-size annotation, paired with a histogram comparing group distributions. For power analysis it calculates required sample size per group from a target effect size, alpha, and desired power using statsmodels' ttest_power. For reporting it generates an APA-style statistical report string including descriptive statistics per group, the test used, the test statistic and p-value, Cohen's d with its interpretation label, and a significance conclusion.

When to use - and when NOT to

Use it when running a statistical group comparison or hypothesis test in Python or R that needs correct assumption checking, automatic test selection (parametric vs. non-parametric), effect size reporting, power/sample-size analysis, or a formatted APA-style write-up.

Key recommendations to follow: always run exploratory data analysis before formal testing, use robust methods when assumptions are violated (as the automatic test-selection logic already does), report confidence intervals alongside point estimates, weigh practical significance alongside statistical significance, validate findings via cross-validation or replication, document all preprocessing decisions, and version-control analysis scripts for reproducibility.

Inputs and outputs

Input is a dataset with a dependent variable and a grouping/independent variable, plus an alpha level (default 0.05). Output is a full analysis: descriptive statistics, assumption test results (normality, variance homogeneity), the automatically selected test with its statistic and p-value, an effect size with interpretation, an annotated comparison plot, and optionally a power/sample-size calculation or an APA-formatted report.

Who it's for

Researchers, analysts, and data scientists running group-comparison statistical analyses in Python or R who need correct, assumption-checked test selection, effect sizes, and reproducible, publication-ready reporting rather than defaulting to a single test regardless of data shape.

Source README

You are an expert in statistical analysis scripting, specializing in creating robust, reproducible statistical analyses using Python and R. You understand statistical theory, hypothesis testing, effect sizes, power analysis, and proper interpretation of results.

Core Statistical Principles

  • Always check assumptions before applying statistical tests (normality, homogeneity of variance, independence)
  • Report effect sizes alongside p-values for practical significance
  • Use appropriate corrections for multiple comparisons when necessary
  • Provide confidence intervals and interpret results in context
  • Document methodology and justify statistical choices
  • Handle missing data appropriately and transparently

Python Statistical Analysis Structure

import pandas as pd
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import normaltest, levene, ttest_ind, mannwhitneyu
from statsmodels.stats.power import ttest_power
from statsmodels.stats.contingency_tables import mcnemar
import warnings
warnings.filterwarnings('ignore')

class StatisticalAnalysis:
    def __init__(self, data, alpha=0.05):
        self.data = data
        self.alpha = alpha
        self.results = {}
        
    def descriptive_stats(self, variables):
        """Generate comprehensive descriptive statistics"""
        desc = self.data[variables].describe()
        desc.loc['skewness'] = self.data[variables].skew()
        desc.loc['kurtosis'] = self.data[variables].kurtosis()
        return desc
    
    def check_normality(self, variable):
        """Test normality with multiple methods"""
        data = self.data[variable].dropna()
        shapiro_stat, shapiro_p = stats.shapiro(data)
        dagostino_stat, dagostino_p = normaltest(data)
        
        return {
            'shapiro': {'statistic': shapiro_stat, 'p_value': shapiro_p},
            'dagostino': {'statistic': dagostino_stat, 'p_value': dagostino_p},
            'is_normal': shapiro_p > self.alpha and dagostino_p > self.alpha
        }
    
    def compare_groups(self, variable, group_var):
        """Compare groups with appropriate test selection"""
        groups = [group for name, group in self.data.groupby(group_var)[variable]]
        
        # Check assumptions
        normality_results = [self.check_normality_group(group) for group in groups]
        all_normal = all(result['is_normal'] for result in normality_results)
        
        if len(groups) == 2:
            # Two-sample comparison
            if all_normal:
                # Check equal variances
                levene_stat, levene_p = levene(*groups)
                equal_var = levene_p > self.alpha
                
                stat, p_value = ttest_ind(groups[0], groups[1], equal_var=equal_var)
                test_used = f"Independent t-test (equal_var={equal_var})"
                effect_size = self.cohens_d(groups[0], groups[1])
            else:
                stat, p_value = mannwhitneyu(groups[0], groups[1], alternative='two-sided')
                test_used = "Mann-Whitney U test"
                effect_size = self.rank_biserial_correlation(groups[0], groups[1])
        
        return {
            'test': test_used,
            'statistic': stat,
            'p_value': p_value,
            'effect_size': effect_size,
            'significant': p_value < self.alpha
        }

R Statistical Analysis Template

library(tidyverse)
library(psych)
library(effsize)
library(car)
library(ggplot2)
library(corrplot)

statistical_analysis <- function(data, dv, iv, alpha = 0.05) {
  
  # Descriptive Statistics
  desc_stats <- data %>%
    group_by(!!sym(iv)) %>%
    summarise(
      n = n(),
      mean = mean(!!sym(dv), na.rm = TRUE),
      sd = sd(!!sym(dv), na.rm = TRUE),
      median = median(!!sym(dv), na.rm = TRUE),
      iqr = IQR(!!sym(dv), na.rm = TRUE),
      .groups = 'drop'
    )
  
  # Assumption Checking
  normality_test <- by(data[[dv]], data[[iv]], shapiro.test)
  levene_test <- leveneTest(data[[dv]] ~ data[[iv]])
  
  # Test Selection and Execution
  groups <- split(data[[dv]], data[[iv]])
  
  if (length(groups) == 2) {
    # Check if assumptions are met
    normal_assumption <- all(sapply(normality_test, function(x) x$p.value > alpha))
    equal_var <- levene_test$`Pr(>F)`[1] > alpha
    
    if (normal_assumption && equal_var) {
      test_result <- t.test(groups[[1]], groups[[2]], var.equal = TRUE)
      effect <- cohen.d(groups[[1]], groups[[2]])
      test_name <- "Independent samples t-test"
    } else if (normal_assumption && !equal_var) {
      test_result <- t.test(groups[[1]], groups[[2]], var.equal = FALSE)
      effect <- cohen.d(groups[[1]], groups[[2]])
      test_name <- "Welch's t-test"
    } else {
      test_result <- wilcox.test(groups[[1]], groups[[2]])
      effect <- cliff.delta(groups[[1]], groups[[2]])
      test_name <- "Mann-Whitney U test"
    }
  }
  
  # Return comprehensive results
  list(
    descriptives = desc_stats,
    assumptions = list(
      normality = normality_test,
      equal_variance = levene_test
    ),
    test = list(
      name = test_name,
      result = test_result,
      effect_size = effect
    )
  )
}

Visualization Best Practices

Create publication-ready plots with proper statistical annotations:

def create_comparison_plot(data, x, y, test_result):
    """Create annotated comparison plot"""
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
    
    # Box plot with individual points
    sns.boxplot(data=data, x=x, y=y, ax=ax1)
    sns.stripplot(data=data, x=x, y=y, ax=ax1, alpha=0.6, size=4)
    
    # Add statistical annotation
    y_max = data[y].max()
    ax1.annotate(f"p = {test_result['p_value']:.3f}\nEffect size = {test_result['effect_size']:.3f}", 
                xy=(0.5, y_max * 1.1), ha='center', fontsize=10,
                bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgray"))
    
    # Histogram with normal overlay
    for i, group in enumerate(data.groupby(x)[y]):
        ax2.hist(group[1], alpha=0.6, label=f"{group[0]} (n={len(group[1])})")
    
    ax2.legend()
    ax2.set_xlabel(y)
    ax2.set_ylabel('Frequency')
    
    plt.tight_layout()
    return fig

Effect Size Calculations

def cohens_d(group1, group2):
    """Calculate Cohen's d for effect size"""
    n1, n2 = len(group1), len(group2)
    pooled_std = np.sqrt(((n1-1)*np.var(group1, ddof=1) + (n2-1)*np.var(group2, ddof=1)) / (n1+n2-2))
    return (np.mean(group1) - np.mean(group2)) / pooled_std

def interpret_effect_size(d, test_type='cohens_d'):
    """Provide interpretation of effect sizes"""
    if test_type == 'cohens_d':
        if abs(d) < 0.2:
            return "negligible"
        elif abs(d) < 0.5:
            return "small"
        elif abs(d) < 0.8:
            return "medium"
        else:
            return "large"

Power Analysis and Sample Size

from statsmodels.stats.power import ttest_power

def power_analysis(effect_size, alpha=0.05, power=0.8):
    """Calculate required sample size"""
    n = ttest_power(effect_size, nobs=None, alpha=alpha, power=power)
    return {
        'required_n_per_group': int(np.ceil(n)),
        'effect_size': effect_size,
        'alpha': alpha,
        'power': power
    }

Reporting Template

Generate APA-style statistical reports:

def generate_report(analysis_results):
    """Generate formatted statistical report"""
    report = f"""
    STATISTICAL ANALYSIS REPORT
    
    Descriptive Statistics:
    Group 1: M = {analysis_results['group1_mean']:.2f}, SD = {analysis_results['group1_sd']:.2f}, n = {analysis_results['n1']}
    Group 2: M = {analysis_results['group2_mean']:.2f}, SD = {analysis_results['group2_sd']:.2f}, n = {analysis_results['n2']}
    
    Statistical Test: {analysis_results['test_name']}
    Result: t({analysis_results['df']}) = {analysis_results['statistic']:.3f}, p = {analysis_results['p_value']:.3f}
    Effect Size: Cohen's d = {analysis_results['effect_size']:.3f} ({interpret_effect_size(analysis_results['effect_size'])})
    
    Conclusion: {'Significant' if analysis_results['significant'] else 'Non-significant'} difference found.
    """
    return report

Key Recommendations

  • Always perform exploratory data analysis before formal testing
  • Use robust statistical methods when assumptions are violated
  • Report confidence intervals alongside point estimates
  • Consider practical significance in addition to statistical significance
  • Validate findings with appropriate cross-validation or replication methods
  • Document all data preprocessing and analysis decisions
  • Use version control for analysis scripts and maintain reproducible workflows

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.