[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7167B28PK20HP7R7ZED2DY0":3,"skill-same:01M7167B28PK20HP7R7ZED2DY0":81},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":14,"repositoryHtmlUrl":58,"repositoryHomepageUrl":6,"ownerHtmlUrl":59,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":60,"install":61,"resources":74},"01M7167B28PK20HP7R7ZED2DY0","statistical-power",null,"Sample size calculation, power analysis, and effect size conversion for scientific studies. Use BEFORE data collection (a priori) to determine required N, or after (post-hoc) to compute achieved power. Covers parametric tests (t-test, ANOVA, chi-square, proportions, correlation, regression), simulation-based power for complex\u002Fclustered\u002Fnested designs, and power curves. Use this skill when someone asks 'how many samples do I need', 'what is my power', 'what effect size can I detect', or any variant. Pairs with \u002Fexperimental-design (choose design first, then compute power) and \u002Fstatistical-analysis (analyze data after collection).","fadrienne\u002FMyGitHub","fadrienne","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F197874571?v=4","01M6X64V8VWCRSMFZ4EPS2BWXG","Francesca Adrienne","01M6X64VD5MW4F9PHDWQKS7ZAF",0,"MIT","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-power\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"statistical power","power","conversion","when","calculation","chi-square","t-test","ANOVA","sample","scipy","uv","design","effect","choose","regression","analyze","Bash","simulation","analysis","collection","2026-11-10 10:12:30",false,"---\nname: statistical-power\ndescription: \"Sample size calculation, power analysis, and effect size conversion for scientific studies. Use BEFORE data collection (a priori) to determine required N, or after (post-hoc) to compute achieved power. Covers parametric tests (t-test, ANOVA, chi-square, proportions, correlation, regression), simulation-based power for complex\u002Fclustered\u002Fnested designs, and power curves. Use this skill when someone asks 'how many samples do I need', 'what is my power', 'what effect size can I detect', or any variant. Pairs with \u002Fexperimental-design (choose design first, then compute power) and \u002Fstatistical-analysis (analyze data after collection).\"\nallowed-tools: Read Write Edit Bash\ncompatibility: \"Python >=3.10. Core: scipy, pingouin, statsmodels, numpy, matplotlib. Install with uv as shown below.\"\nlicense: MIT license\nmetadata: {\"version\": \"1.0\", \"skill-author\": \"K-Dense Inc.\"}\n---\n\n# Statistical Power\n\n## Overview\n\nPower analysis answers three questions before you collect data:\n\n1. **A priori (most common)** — Given a desired power, significance level, and effect size, how large a sample do I need?\n2. **Sensitivity** — Given my actual N and significance level, what is the smallest effect I can detect at 80% power?\n3. **Post-hoc** — Given my actual N and effect size, what was my achieved power?\n\n**Power (1 − β)** is the probability of correctly rejecting H₀ when the effect is real. Convention: 0.80 is the minimum acceptable; 0.90 or 0.95 for high-stakes decisions.\n\n**Significance level (α)** is the tolerable Type I error rate. Convention: 0.05 for most research; 0.01 or lower for multiple-testing contexts.\n\n**Effect size** is a standardized, scale-free measure of the magnitude of the effect. See the Effect Size Reference below.\n\n---\n\n## Installation\n\n```bash\nuv pip install \"scipy>=1.11\" \"pingouin>=0.6\" \"statsmodels>=0.14\" \"numpy>=1.26\" \"matplotlib>=3.8\"\n```\n\n---\n\n## When to Use This Skill\n\n- Designing a study and need to know how many subjects\u002Fsamples to recruit\n- Reviewer asks \"was the study adequately powered?\"\n- Writing a grant or protocol that requires a power justification\n- Computing the minimum detectable effect for a fixed budget (N is constrained)\n- Powering a complex design (nested, clustered, repeated-measures) where formulas don't exist\n- Plotting power curves to communicate the sample-size trade-off\n\n---\n\n## Workflow\n\n### Step 1 — Identify the primary analysis\n\nAsk (or infer) what statistical test will answer the primary research question. Power is test-specific. Common mappings:\n\n| Research question | Test | Effect size metric |\n|---|---|---|\n| Compare two group means | Independent t-test | Cohen's d |\n| Compare paired\u002Fpre-post means | Paired t-test | Cohen's d |\n| Compare ≥3 group means | One-way ANOVA | Cohen's f |\n| Test association in a contingency table | Chi-square | Cohen's w |\n| Test difference in two proportions | Proportions z-test | h (arcsine diff) |\n| Test correlation ≠ 0 | Pearson r test | r |\n| Regression: does the model explain variance? | F-test (regression) | Cohen's f² |\n| Survival comparison | Log-rank test | hazard ratio |\n| Clustered\u002Fnested data | Simulation | ICC + design effect |\n\n### Step 2 — Choose or estimate the effect size\n\nUse one of these sources, in order of preference:\n\n1. **Prior literature** — meta-analytic estimates, pilot data\n2. **Minimum clinically \u002F scientifically meaningful difference** — the smallest effect that would change decisions\n3. **Cohen's conventions** (last resort) — small\u002Fmedium\u002Flarge (see table below). Note: conventions are field-specific and often under-powered.\n\n### Step 3 — Run the calculation\n\nUse the scripts in `scripts\u002Fpower_analysis.py` or the inline patterns below.\n\n### Step 4 — Report\n\nAlways report: test, α, target power (1−β), effect size and its source, resulting N per group\u002Farm, and total N.\n\n---\n\n## Closed-Form Power Calculations\n\n### Independent samples t-test\n\n```python\nfrom scipy.stats import norm\nimport numpy as np\n\ndef power_ttest(d, n, alpha=0.05, tails=2):\n    \"\"\"Power of an independent-samples t-test given Cohen's d and n per group.\"\"\"\n    se = np.sqrt(2 \u002F n)\n    ncp = d \u002F se  # non-centrality parameter (approx, large N)\n    crit = norm.ppf(1 - alpha \u002F tails)\n    power = 1 - norm.cdf(crit - ncp) + norm.cdf(-crit - ncp)\n    return power\n\ndef n_ttest(d, power=0.80, alpha=0.05, tails=2):\n    \"\"\"Required n per group for an independent-samples t-test.\"\"\"\n    from statsmodels.stats.power import TTestIndPower\n    analysis = TTestIndPower()\n    n = analysis.solve_power(effect_size=d, power=power, alpha=alpha,\n                             alternative='two-sided' if tails == 2 else 'larger')\n    return np.ceil(n)\n\n# Example: detect d=0.5 with 80% power, α=0.05\nprint(n_ttest(d=0.5))  # → 64 per group, 128 total\n```\n\n### Paired t-test\n\n```python\nfrom statsmodels.stats.power import TTestPower\n\ndef n_paired_ttest(d, power=0.80, alpha=0.05):\n    analysis = TTestPower()\n    n = analysis.solve_power(effect_size=d, power=power, alpha=alpha)\n    return np.ceil(n)\n\nprint(n_paired_ttest(d=0.5))  # → 34 pairs\n```\n\n### One-way ANOVA\n\n```python\nfrom statsmodels.stats.power import FtestAnovaPower\n\ndef n_anova(f, k, power=0.80, alpha=0.05):\n    \"\"\"n per group for one-way ANOVA with k groups and Cohen's f.\"\"\"\n    analysis = FtestAnovaPower()\n    n = analysis.solve_power(effect_size=f, power=power, alpha=alpha, k_groups=k)\n    return np.ceil(n)\n\nprint(n_anova(f=0.25, k=3))  # → 52 per group, 156 total\n```\n\n### Chi-square test\n\n```python\nfrom statsmodels.stats.power import GofChisquarePower\n\ndef n_chisq(w, df, power=0.80, alpha=0.05):\n    \"\"\"N for a chi-square goodness-of-fit or association test.\n    df = (rows-1)*(cols-1) for association tables.\"\"\"\n    analysis = GofChisquarePower()\n    n = analysis.solve_power(effect_size=w, power=power, alpha=alpha, n_bins=df+1)\n    return np.ceil(n)\n```\n\n### Proportions test\n\n```python\nfrom statsmodels.stats.proportion import proportion_effectsize\nfrom statsmodels.stats.power import NormalIndPower\n\ndef n_proportions(p1, p2, power=0.80, alpha=0.05):\n    \"\"\"N per group to detect difference between proportions p1 and p2.\"\"\"\n    h = proportion_effectsize(p1, p2)\n    analysis = NormalIndPower()\n    n = analysis.solve_power(effect_size=h, power=power, alpha=alpha)\n    return np.ceil(n), h\n\nn, h = n_proportions(0.20, 0.35)\nprint(f\"h={h:.3f}, n per group={n}\")\n```\n\n### Pearson correlation\n\n```python\nimport pingouin as pg\n\nresult = pg.power_corr(r=0.30, n=None, power=0.80, alpha=0.05, alternative='two-sided')\nprint(result)  # n=84\n```\n\n### Multiple regression (R² increment)\n\n```python\nfrom statsmodels.stats.power import FtestPower\n\ndef n_regression(f2, u, power=0.80, alpha=0.05):\n    \"\"\"N for testing R² increment in multiple regression.\n    f2 = Cohen's f² for the tested predictors.\n    u = degrees of freedom for the tested predictors.\"\"\"\n    analysis = FtestPower()\n    n = analysis.solve_power(effect_size=f2, df_num=u, power=power, alpha=alpha)\n    return np.ceil(n + u + 1)  # total N\n\nprint(n_regression(f2=0.15, u=3))\n```\n\n---\n\n## Power Curves\n\nPlot power vs. N for a range of effect sizes to communicate the trade-off:\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom statsmodels.stats.power import TTestIndPower\n\nanalysis = TTestIndPower()\nns = np.arange(10, 200, 5)\nfig, ax = plt.subplots(figsize=(7, 4))\n\nfor d, label in [(0.2, 'small (d=0.2)'), (0.5, 'medium (d=0.5)'), (0.8, 'large (d=0.8)')]:\n    powers = [analysis.solve_power(effect_size=d, nobs1=n, alpha=0.05) for n in ns]\n    ax.plot(ns, powers, label=label)\n\nax.axhline(0.80, color='gray', linestyle='--', label='80% power')\nax.axhline(0.90, color='gray', linestyle=':', label='90% power')\nax.set_xlabel('N per group')\nax.set_ylabel('Power (1 − β)')\nax.set_title('Power curves — independent t-test (α = 0.05)')\nax.legend()\nax.set_ylim(0, 1)\nplt.tight_layout()\nplt.savefig('power_curve.png', dpi=150)\n```\n\n---\n\n## Simulation-Based Power\n\nUse simulation when:\n- The design is clustered, nested, or mixed (ICC matters)\n- The outcome is non-normal (binary, count, ordinal, skewed)\n- You have multiple primary outcomes\n- The test statistic has no standard closed form\n\n```python\nimport numpy as np\nfrom scipy import stats\n\ndef simulate_power_clustered(n_clusters, n_per_cluster, icc, delta,\n                              sigma_total=1.0, alpha=0.05, n_sim=2000, seed=42):\n    \"\"\"\n    Power for comparing two arms of a cluster-randomized trial.\n    \n    Parameters\n    ----------\n    n_clusters : int   — clusters per arm\n    n_per_cluster : int — subjects per cluster\n    icc : float        — intraclass correlation (0 to 1)\n    delta : float      — true mean difference between arms\n    sigma_total : float — total SD\n    \"\"\"\n    rng = np.random.default_rng(seed)\n    sigma_b = np.sqrt(icc * sigma_total**2)          # between-cluster SD\n    sigma_w = np.sqrt((1 - icc) * sigma_total**2)    # within-cluster SD\n    reject = 0\n\n    for _ in range(n_sim):\n        # Arm 0\n        cluster_effects_0 = rng.normal(0, sigma_b, n_clusters)\n        arm0 = np.concatenate([\n            rng.normal(cluster_effects_0[c], sigma_w, n_per_cluster)\n            for c in range(n_clusters)\n        ])\n        # Arm 1\n        cluster_effects_1 = rng.normal(delta, sigma_b, n_clusters)\n        arm1 = np.concatenate([\n            rng.normal(cluster_effects_1[c], sigma_w, n_per_cluster)\n            for c in range(n_clusters)\n        ])\n        _, p = stats.ttest_ind(arm0, arm1)\n        reject += p \u003C alpha\n\n    return reject \u002F n_sim\n\n# Example: 10 clusters\u002Farm, 20 subjects\u002Fcluster, ICC=0.05, d=0.5\npower = simulate_power_clustered(10, 20, icc=0.05, delta=0.5)\nprint(f\"Simulated power: {power:.3f}\")\n```\n\n**Design effect (DEFF) shortcut** — for a rough adjustment without simulation:\n\n```python\ndef design_effect(icc, n_per_cluster):\n    \"\"\"DEFF = 1 + (n-1) * ICC. Multiply required N_simple by DEFF.\"\"\"\n    return 1 + (n_per_cluster - 1) * icc\n\n# If simple t-test needs 64\u002Farm, and DEFF=1.95:\nn_simple = 64\ndeff = design_effect(icc=0.05, n_per_cluster=20)\nn_adjusted = np.ceil(n_simple * deff)\nprint(f\"DEFF={deff:.2f}, adjusted N per arm={n_adjusted}\")\n```\n\n---\n\n## Effect Size Reference\n\n### Conventions (Cohen, 1988)\n\n| Test | Metric | Small | Medium | Large |\n|---|---|---|---|---|\n| t-test | d | 0.20 | 0.50 | 0.80 |\n| ANOVA | f | 0.10 | 0.25 | 0.40 |\n| Chi-square \u002F proportions | w | 0.10 | 0.30 | 0.50 |\n| Correlation | r | 0.10 | 0.30 | 0.50 |\n| Regression (R² increment) | f² | 0.02 | 0.15 | 0.35 |\n\n**Warning**: Cohen's conventions are rough defaults derived from social psychology in 1988. They are not calibrated to your field. Always prefer an effect size from prior literature or a minimum clinically meaningful difference.\n\n### Conversions\n\n```python\nimport numpy as np\n\ndef d_from_means(m1, m2, sd_pooled):\n    return (m1 - m2) \u002F sd_pooled\n\ndef d_from_t(t, n1, n2):\n    return t * np.sqrt((n1 + n2) \u002F (n1 * n2))\n\ndef r_from_d(d):\n    return d \u002F np.sqrt(d**2 + 4)\n\ndef d_from_r(r):\n    return 2 * r \u002F np.sqrt(1 - r**2)\n\ndef f_from_eta2(eta2):\n    return np.sqrt(eta2 \u002F (1 - eta2))\n\ndef eta2_from_f(f):\n    return f**2 \u002F (1 + f**2)\n\ndef OR_to_d(OR):\n    return np.log(OR) * (np.sqrt(3) \u002F np.pi)\n```\n\n---\n\n## Common Mistakes\n\n1. **Using post-hoc power to interpret a null result** — post-hoc power is circular (it's entirely determined by the observed p-value) and tells you nothing about whether the null is true. Use confidence intervals on the effect size instead.\n\n2. **Ignoring attrition** — inflate the required N by the expected dropout rate: `N_enrolled = N_required \u002F (1 - dropout_rate)`.\n\n3. **Single primary outcome** — power calculations apply to your *primary* outcome. Secondary outcomes will be underpowered. Do not adjust for multiplicity in the power calculation unless you are powering for a composite outcome.\n\n4. **Using variance from a different population or measurement** — the SD estimate must match your specific population and measurement instrument.\n\n5. **Ignoring the design effect for clustered data** — forgetting ICC inflates apparent power. Always compute DEFF for clustered designs.\n\n---\n\n## Integration\n\n- **`\u002Fexperimental-design`** — determines the study design; call `\u002Fstatistical-power` after design is fixed\n- **`\u002Fstatistical-analysis`** — analyzes data after collection; reports observed effect size and CI\n- **`\u002Fscientificwriting`** — includes the power justification in the Methods section\n","# Statistical Power\n\n## Overview\n\nPower analysis answers three questions before you collect data:\n\n1. **A priori (most common)** — Given a desired power, significance level, and effect size, how large a sample do I need?\n2. **Sensitivity** — Given my actual N and significance level, what is the smallest effect I can detect at 80% power?\n3. **Post-hoc** — Given my actual N and effect size, what was my achieved power?\n\n**Power (1 − β)** is the probability of correctly rejecting H₀ when the effect is real. Convention: 0.80 is the minimum acceptable; 0.90 or 0.95 for high-stakes decisions.\n\n**Significance level (α)** is the tolerable Type I error rate. Convention: 0.05 for most research; 0.01 or lower for multiple-testing contexts.\n\n**Effect size** is a standardized, scale-free measure of the magnitude of the effect. See the Effect Size Reference below.\n\n---\n\n## Installation\n\n```bash\nuv pip install \"scipy>=1.11\" \"pingouin>=0.6\" \"statsmodels>=0.14\" \"numpy>=1.26\" \"matplotlib>=3.8\"\n```\n\n---\n\n## When to Use This Skill\n\n- Designing a study and need to know how many subjects\u002Fsamples to recruit\n- Reviewer asks \"was the study adequately powered?\"\n- Writing a grant or protocol that requires a power justification\n- Computing the minimum detectable effect for a fixed budget (N is constrained)\n- Powering a complex design (nested, clustered, repeated-measures) where formulas don't exist\n- Plotting power curves to communicate the sample-size trade-off\n\n---\n\n## Workflow\n\n### Step 1 — Identify the primary analysis\n\nAsk (or infer) what statistical test will answer the primary research question. Power is test-specific. Common mappings:\n\n| Research question | Test | Effect size metric |\n|---|---|---|\n| Compare two group means | Independent t-test | Cohen's d |\n| Compare paired\u002Fpre-post means | Paired t-test | Cohen's d |\n| Compare ≥3 group means | One-way ANOVA | Cohen's f |\n| Test association in a contingency table | Chi-square | Cohen's w |\n| Test difference in two proportions | Proportions z-test | h (arcsine diff) |\n| Test correlation ≠ 0 | Pearson r test | r |\n| Regression: does the model explain variance? | F-test (regression) | Cohen's f² |\n| Survival comparison | Log-rank test | hazard ratio |\n| Clustered\u002Fnested data | Simulation | ICC + design effect |\n\n### Step 2 — Choose or estimate the effect size\n\nUse one of these sources, in order of preference:\n\n1. **Prior literature** — meta-analytic estimates, pilot data\n2. **Minimum clinically \u002F scientifically meaningful difference** — the smallest effect that would change decisions\n3. **Cohen's conventions** (last resort) — small\u002Fmedium\u002Flarge (see table below). Note: conventions are field-specific and often under-powered.\n\n### Step 3 — Run the calculation\n\nUse the scripts in `scripts\u002Fpower_analysis.py` or the inline patterns below.\n\n### Step 4 — Report\n\nAlways report: test, α, target power (1−β), effect size and its source, resulting N per group\u002Farm, and total N.\n\n---\n\n## Closed-Form Power Calculations\n\n### Independent samples t-test\n\n```python\nfrom scipy.stats import norm\nimport numpy as np\n\ndef power_ttest(d, n, alpha=0.05, tails=2):\n    \"\"\"Power of an independent-samples t-test given Cohen's d and n per group.\"\"\"\n    se = np.sqrt(2 \u002F n)\n    ncp = d \u002F se  # non-centrality parameter (approx, large N)\n    crit = norm.ppf(1 - alpha \u002F tails)\n    power = 1 - norm.cdf(crit - ncp) + norm.cdf(-crit - ncp)\n    return power\n\ndef n_ttest(d, power=0.80, alpha=0.05, tails=2):\n    \"\"\"Required n per group for an independent-samples t-test.\"\"\"\n    from statsmodels.stats.power import TTestIndPower\n    analysis = TTestIndPower()\n    n = analysis.solve_power(effect_size=d, power=power, alpha=alpha,\n                             alternative='two-sided' if tails == 2 else 'larger')\n    return np.ceil(n)\n\n# Example: detect d=0.5 with 80% power, α=0.05\nprint(n_ttest(d=0.5))  # → 64 per group, 128 total\n```\n\n### Paired t-test\n\n```python\nfrom statsmodels.stats.power import TTestPower\n\ndef n_paired_ttest(d, power=0.80, alpha=0.05):\n    analysis = TTestPower()\n    n = analysis.solve_power(effect_size=d, power=power, alpha=alpha)\n    return np.ceil(n)\n\nprint(n_paired_ttest(d=0.5))  # → 34 pairs\n```\n\n### One-way ANOVA\n\n```python\nfrom statsmodels.stats.power import FtestAnovaPower\n\ndef n_anova(f, k, power=0.80, alpha=0.05):\n    \"\"\"n per group for one-way ANOVA with k groups and Cohen's f.\"\"\"\n    analysis = FtestAnovaPower()\n    n = analysis.solve_power(effect_size=f, power=power, alpha=alpha, k_groups=k)\n    return np.ceil(n)\n\nprint(n_anova(f=0.25, k=3))  # → 52 per group, 156 total\n```\n\n### Chi-square test\n\n```python\nfrom statsmodels.stats.power import GofChisquarePower\n\ndef n_chisq(w, df, power=0.80, alpha=0.05):\n    \"\"\"N for a chi-square goodness-of-fit or association test.\n    df = (rows-1)*(cols-1) for association tables.\"\"\"\n    analysis = GofChisquarePower()\n    n = analysis.solve_power(effect_size=w, power=power, alpha=alpha, n_bins=df+1)\n    return np.ceil(n)\n```\n\n### Proportions test\n\n```python\nfrom statsmodels.stats.proportion import proportion_effectsize\nfrom statsmodels.stats.power import NormalIndPower\n\ndef n_proportions(p1, p2, power=0.80, alpha=0.05):\n    \"\"\"N per group to detect difference between proportions p1 and p2.\"\"\"\n    h = proportion_effectsize(p1, p2)\n    analysis = NormalIndPower()\n    n = analysis.solve_power(effect_size=h, power=power, alpha=alpha)\n    return np.ceil(n), h\n\nn, h = n_proportions(0.20, 0.35)\nprint(f\"h={h:.3f}, n per group={n}\")\n```\n\n### Pearson correlation\n\n```python\nimport pingouin as pg\n\nresult = pg.power_corr(r=0.30, n=None, power=0.80, alpha=0.05, alternative='two-sided')\nprint(result)  # n=84\n```\n\n### Multiple regression (R² increment)\n\n```python\nfrom statsmodels.stats.power import FtestPower\n\ndef n_regression(f2, u, power=0.80, alpha=0.05):\n    \"\"\"N for testing R² increment in multiple regression.\n    f2 = Cohen's f² for the tested predictors.\n    u = degrees of freedom for the tested predictors.\"\"\"\n    analysis = FtestPower()\n    n = analysis.solve_power(effect_size=f2, df_num=u, power=power, alpha=alpha)\n    return np.ceil(n + u + 1)  # total N\n\nprint(n_regression(f2=0.15, u=3))\n```\n\n---\n\n## Power Curves\n\nPlot power vs. N for a range of effect sizes to communicate the trade-off:\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom statsmodels.stats.power import TTestIndPower\n\nanalysis = TTestIndPower()\nns = np.arange(10, 200, 5)\nfig, ax = plt.subplots(figsize=(7, 4))\n\nfor d, label in [(0.2, 'small (d=0.2)'), (0.5, 'medium (d=0.5)'), (0.8, 'large (d=0.8)')]:\n    powers = [analysis.solve_power(effect_size=d, nobs1=n, alpha=0.05) for n in ns]\n    ax.plot(ns, powers, label=label)\n\nax.axhline(0.80, color='gray', linestyle='--', label='80% power')\nax.axhline(0.90, color='gray', linestyle=':', label='90% power')\nax.set_xlabel('N per group')\nax.set_ylabel('Power (1 − β)')\nax.set_title('Power curves — independent t-test (α = 0.05)')\nax.legend()\nax.set_ylim(0, 1)\nplt.tight_layout()\nplt.savefig('power_curve.png', dpi=150)\n```\n\n---\n\n## Simulation-Based Power\n\nUse simulation when:\n- The design is clustered, nested, or mixed (ICC matters)\n- The outcome is non-normal (binary, count, ordinal, skewed)\n- You have multiple primary outcomes\n- The test statistic has no standard closed form\n\n```python\nimport numpy as np\nfrom scipy import stats\n\ndef simulate_power_clustered(n_clusters, n_per_cluster, icc, delta,\n                              sigma_total=1.0, alpha=0.05, n_sim=2000, seed=42):\n    \"\"\"\n    Power for comparing two arms of a cluster-randomized trial.\n    \n    Parameters\n    ----------\n    n_clusters : int   — clusters per arm\n    n_per_cluster : int — subjects per cluster\n    icc : float        — intraclass correlation (0 to 1)\n    delta : float      — true mean difference between arms\n    sigma_total : float — total SD\n    \"\"\"\n    rng = np.random.default_rng(seed)\n    sigma_b = np.sqrt(icc * sigma_total**2)          # between-cluster SD\n    sigma_w = np.sqrt((1 - icc) * sigma_total**2)    # within-cluster SD\n    reject = 0\n\n    for _ in range(n_sim):\n        # Arm 0\n        cluster_effects_0 = rng.normal(0, sigma_b, n_clusters)\n        arm0 = np.concatenate([\n            rng.normal(cluster_effects_0[c], sigma_w, n_per_cluster)\n            for c in range(n_clusters)\n        ])\n        # Arm 1\n        cluster_effects_1 = rng.normal(delta, sigma_b, n_clusters)\n        arm1 = np.concatenate([\n            rng.normal(cluster_effects_1[c], sigma_w, n_per_cluster)\n            for c in range(n_clusters)\n        ])\n        _, p = stats.ttest_ind(arm0, arm1)\n        reject += p \u003C alpha\n\n    return reject \u002F n_sim\n\n# Example: 10 clusters\u002Farm, 20 subjects\u002Fcluster, ICC=0.05, d=0.5\npower = simulate_power_clustered(10, 20, icc=0.05, delta=0.5)\nprint(f\"Simulated power: {power:.3f}\")\n```\n\n**Design effect (DEFF) shortcut** — for a rough adjustment without simulation:\n\n```python\ndef design_effect(icc, n_per_cluster):\n    \"\"\"DEFF = 1 + (n-1) * ICC. Multiply required N_simple by DEFF.\"\"\"\n    return 1 + (n_per_cluster - 1) * icc\n\n# If simple t-test needs 64\u002Farm, and DEFF=1.95:\nn_simple = 64\ndeff = design_effect(icc=0.05, n_per_cluster=20)\nn_adjusted = np.ceil(n_simple * deff)\nprint(f\"DEFF={deff:.2f}, adjusted N per arm={n_adjusted}\")\n```\n\n---\n\n## Effect Size Reference\n\n### Conventions (Cohen, 1988)\n\n| Test | Metric | Small | Medium | Large |\n|---|---|---|---|---|\n| t-test | d | 0.20 | 0.50 | 0.80 |\n| ANOVA | f | 0.10 | 0.25 | 0.40 |\n| Chi-square \u002F proportions | w | 0.10 | 0.30 | 0.50 |\n| Correlation | r | 0.10 | 0.30 | 0.50 |\n| Regression (R² increment) | f² | 0.02 | 0.15 | 0.35 |\n\n**Warning**: Cohen's conventions are rough defaults derived from social psychology in 1988. They are not calibrated to your field. Always prefer an effect size from prior literature or a minimum clinically meaningful difference.\n\n### Conversions\n\n```python\nimport numpy as np\n\ndef d_from_means(m1, m2, sd_pooled):\n    return (m1 - m2) \u002F sd_pooled\n\ndef d_from_t(t, n1, n2):\n    return t * np.sqrt((n1 + n2) \u002F (n1 * n2))\n\ndef r_from_d(d):\n    return d \u002F np.sqrt(d**2 + 4)\n\ndef d_from_r(r):\n    return 2 * r \u002F np.sqrt(1 - r**2)\n\ndef f_from_eta2(eta2):\n    return np.sqrt(eta2 \u002F (1 - eta2))\n\ndef eta2_from_f(f):\n    return f**2 \u002F (1 + f**2)\n\ndef OR_to_d(OR):\n    return np.log(OR) * (np.sqrt(3) \u002F np.pi)\n```\n\n---\n\n## Common Mistakes\n\n1. **Using post-hoc power to interpret a null result** — post-hoc power is circular (it's entirely determined by the observed p-value) and tells you nothing about whether the null is true. Use confidence intervals on the effect size instead.\n\n2. **Ignoring attrition** — inflate the required N by the expected dropout rate: `N_enrolled = N_required \u002F (1 - dropout_rate)`.\n\n3. **Single primary outcome** — power calculations apply to your *primary* outcome. Secondary outcomes will be underpowered. Do not adjust for multiplicity in the power calculation unless you are powering for a composite outcome.\n\n4. **Using variance from a different population or measurement** — the SD estimate must match your specific population and measurement instrument.\n\n5. **Ignoring the design effect for clustered data** — forgetting ICC inflates apparent power. Always compute DEFF for clustered designs.\n\n---\n\n## Integration\n\n- **`\u002Fexperimental-design`** — determines the study design; call `\u002Fstatistical-power` after design is fixed\n- **`\u002Fstatistical-analysis`** — analyzes data after collection; reports observed effect size and CI\n- **`\u002Fscientificwriting`** — includes the power justification in the Methods section\n",{"name":5,"license":49,"metadata":50,"description":7,"allowed-tools":53,"compatibility":54},"MIT license",{"version":51,"skill-author":52},"1.0","K-Dense Inc.","Read Write Edit Bash","Python >=3.10. Core: scipy, pingouin, statsmodels, numpy, matplotlib. Install with uv as shown below.","main","4aa39efd1cdab0b4657ecee16c92a92011a5b10f","scientific-agent-skills\u002Fskills\u002Fstatistical-power","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub","https:\u002F\u002Fgithub.com\u002Ffadrienne","2026-10-28 00:43:09",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add fadrienne\u002FMyGitHub --skill statistical-power",{"tool":67,"command":68},"bunx","bunx skills add fadrienne\u002FMyGitHub --skill statistical-power",{"tool":70,"command":71},"pnpm","pnpm dlx skills add fadrienne\u002FMyGitHub --skill statistical-power","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-power\u002FSKILL.md",true,[75],{"path":76,"resourceType":77,"resourceTypeDesc":78,"sizeBytes":79,"sourceHtmlUrl":80},"scripts\u002Fpower_analysis.py","SCRIPT","脚本",9945,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-power\u002Fscripts\u002Fpower_analysis.py",[82,109,143,170,197,224],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":91,"publishedAt":44},"01M71677EBCM8EPCE9BZCK8505","statistical-analysis","Guided statistical analysis with test selection and reporting. Use when you need help choosing appropriate tests for your data, assumption checking, power analysis, and APA-formatted results. Best for academic research reporting, test selection guidance. For implementing specific models programmatically use statsmodels.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-analysis\u002FSKILL.md",[88],{"categoryNo":89,"categoryName":90,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[42,92,25,93,94,95,27,96,97,98,99,100,101,102,103,104,105,106,107,108],"statistical analysis","academic research","implementing","selection","you","reporting","data","for","tests","use","with","test","research","results","statsmodels","models","help",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":124,"publishedAt":44},"01M71673R93XAHFH81DBNVNG7H","scientific-writing","Core skill for the deep research and writing tool. Write scientific manuscripts in full paragraphs (never bullet points). Use two-stage process with (1) section outlines with key points using research-lookup then (2) convert to flowing prose. IMRAD structure, citations (APA\u002FAMA\u002FVancouver), figures\u002Ftables, reporting guidelines (CONSORT\u002FSTROBE\u002FPRISMA), for research papers and journal submissions.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fscientific-writing\u002FSKILL.md",[115,118,119],{"categoryNo":116,"categoryName":117,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":120,"categoryName":121,"taxonomyType":122,"taxonomyTypeDesc":123},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[125,126,127,128,129,130,131,132,133,134,40,135,136,137,138,139,140,141,97,142],"writing","scientific","scientific writing","Citations","deep","deep research","never","papers","journal","false","api","prisma","structure","openrouter","Outlines","core skill","read","features",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":153,"publishedAt":44},"01M7166ZPKXBF4EBPHVTJPQBB1","scientific-visualization","Meta-skill for publication-ready figures. Use when creating journal submission figures requiring multi-panel layouts, significance annotations, error bars, colorblind-safe palettes, and specific journal formatting (Nature, Science, Cell). Orchestrates matplotlib\u002Fseaborn\u002Fplotly with publication styles. For quick exploration use seaborn or plotly directly.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fscientific-visualization\u002FSKILL.md",[149,152],{"categoryNo":150,"categoryName":151,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[154,126,155,156,157,158,159,160,161,133,27,162,163,164,165,166,167,168,99,169],"visualization","scientific visualization","error","ready","quick","exploration","meta-skill","Meta","safe","plotly","annotations","formatting","Publication","figures","panel","submission",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":182,"publishedAt":44},"01M7166VXJWQSSC3RQZP60WBGR","research-code","Debug, profile, review, and restructure Python research and analysis code. Use when analysis scripts crash, produce wrong results, run too slowly, or need a correctness review. Covers: reading tracebacks and diagnosing root causes, hypothesis-driven debugging, reviewing code for common statistical\u002Fnumerical errors, profiling data pipelines, improving reproducibility (seeds, environments, determinism), and structuring analysis scripts for sharing. Distinct from \u002Fexploratory-data-analysis (which understands data) and \u002Fstatistical-analysis (which chooses and runs tests) — this skill focuses on the code itself.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fresearch-code\u002FSKILL.md",[176,179],{"categoryNo":177,"categoryName":178,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":180,"categoryName":181,"taxonomyType":122,"taxonomyTypeDesc":123},"01JBSEEDCAT000000000000030","开发工程师",[183,184,104,185,186,187,188,34,189,27,40,42,190,191,192,193,194,195,141,196],"code","research code","which","memory","data-analysis","errors","debugging","common","review","data pipelines","run","scripts","line","write",{"skillNo":198,"name":199,"nameZh":6,"description":200,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":201,"licenseFileUrl":6,"sourceHtmlUrl":202,"categories":203,"keywords":210,"publishedAt":44},"01M7166CF5HSR7SVZYZFWTDX55","markdown-mermaid-writing","Comprehensive markdown and Mermaid diagram writing skill. Use when creating any scientific document, report, analysis, or visualization. Establishes text-based diagrams as the default documentation standard with full style guides (markdown + mermaid), 24 diagram type references, and 9 document templates.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fmarkdown-mermaid-writing\u002FSKILL.md",[204,207,208,209],{"categoryNo":205,"categoryName":206,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理",{"categoryNo":116,"categoryName":117,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":120,"categoryName":121,"taxonomyType":122,"taxonomyTypeDesc":123},[125,211,212,213,214,215,154,216,217,27,40,42,218,219,220,221,222,223,126,141],"markdown mermaid writing","mermaid","markdown","community","diagrams","project","default","team","guides","text","documentation","references","diagram",{"skillNo":225,"name":226,"nameZh":6,"description":227,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":228,"categories":229,"keywords":238,"publishedAt":44},"01M716618J5EDTN4RW41JZ4W4Z","hypothesis-generation","Structured hypothesis formulation from observations. Use when you have experimental observations or data and need to formulate testable hypotheses with predictions, propose mechanisms, and design experiments to test them. Follows scientific method framework. For open-ended ideation use scientific-brainstorming; for automated LLM-driven hypothesis testing on datasets use hypogenic.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fhypothesis-generation\u002FSKILL.md",[230,231,234,235],{"categoryNo":89,"categoryName":90,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":232,"categoryName":233,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":236,"categoryName":237,"taxonomyType":122,"taxonomyTypeDesc":123},"01JBSEEDCAT000000000000032","设计师",[239,240,241,242,243,35,134,27,244,96,40,135,138,126,245,141,142,196,246,98],"hypothesis generation","generation","hypothesis","testing","open","predictions","hypothesis formulation","edit"]