| name | psy-ana-coder |
| description | Use for generating data analysis scripts (R or Python) from a completed analysis config YAML. Reads the analysis config and generates reproducible scripts with inline documentation, statistical modeling, assumption checks, sensitivity analysis, publication-quality figures, and reports. Does NOT design analyses — that is psy-ana-designer's job. Trigger for 生成分析代码、analysis script、R分析、Python分析 / 分析コード生成、R分析コード / Analyse-Code generieren, R-Analyse, Python-Analyse / generer code analyse, analyse R, analyse Python. |
| version | 1.3 |
| status | stable |
Analysis Coder
Version
v1.3 — stable, 2026-06-10. Sub-skill of amazing-psycoder.
Purpose
Receives the analysis config YAML produced by psy-ana-designer, and generates either R or Python analysis scripts according to the user's language preference. R and Python share the same analysis logic — config field mapping, model selection, figure types, and report structure are fully identical; the only differences lie in the specific API calls.
Does not design analyses — only implements a confirmed analysis plan.
Platform Routing
Analysis config YAML
│
├── User language = R → r/ (tidyverse, lme4, ggplot2, RMarkdown)
└── User language = Python → python/ (pandas, statsmodels, seaborn, Jupyter)
Each platform includes 4 components: spec/ (API specification + anti-patterns), mapping/ (config-to-code mappings), checklist/ (audit checklist items), demo/ (complete example).
Phase 0: Config Ingestion & Validation
Goal: Receive and validate the analysis config YAML, and confirm the language preference.
0.1 Receive Config
"Please provide the analysis config YAML generated by psy-ana-designer. You may paste its content, or provide a file path (e.g., analysis_config.yaml)."
Validate immediately after reading the config:
version field exists and is compatible (currently supports v1.0)
- Required fields:
design.design_type, design.dvs, model.seed
- At least one
questions[] entry
- Field types are correct (
rt_lower is numeric, correction is an allowed value, etc.)
Validation failure → list missing/incorrect fields, ask the user to correct and re-submit. Do not proceed.
0.2 Language Confirmation
"Should the analysis script use R or Python?"
Route to the corresponding platform (r/ or python/) based on the answer. If the user has no preference, default to R (more mature ecosystem).
0.3 Generate Preview
Display the generation plan:
- Platform: R / Python
- Model: {model types extracted from config}
- Figures: {figure list extracted from config}
- Output files: analysis.R/py + report.Rmd/ipynb
"Confirm the plan above is correct? Then code generation will begin."
After user confirmation, proceed to generation.
Red Lines
| # | Rule |
|---|
| 1 | Seed not set → do not deliver |
| 2 | Exclusion log missing → do not deliver |
| 3 | Assumption test code missing → do not deliver |
| 4 | Effect size code missing → do not deliver |
| 5 | Multiple comparison scheme not reflected → do not deliver |
| 6 | Environment info (sessionInfo/sys.version) not output → do not deliver |
| 7 | Never generate code with hardcoded paths |
| 8 | Comment language MUST match user language → do not deliver |
Shared Analysis Logic
The logic below applies to both R and Python equally. For platform-specific API mappings, see each platform's mapping/ file.
Comment Language Specification (Highest Priority)
All generated code comments must use the user's language. Chinese user → Chinese comments, English user → English comments. Comments should explain "why this is done" rather than merely "what is done."
Each step's comments should include:
- The purpose of this step (why this step is necessary)
- The meaning of key parameters (e.g., "RT lower bound of 150 ms; values below this are treated as anticipatory responses")
- The rationale for the chosen statistical method (e.g., "Using lmer instead of paired t-test because it can leverage all trial-level data")
- Result interpretation hints (e.g., "p > 0.05 indicates failure to reject the normality assumption")
The comment style follows "pedagogical comments" — enabling a colleague unfamiliar with this analysis method to understand what every step does and why it is done.
12-Step Script Structure
1. Title comment Experiment name, model, date, seed
2. Environment setup Package loading, seed, global options
3. Data import Read + column name validation (missing column → error)
4. Data cleaning RT filtering → correct trials → participant exclusion → SD exclusion → missing data handling
5. Exclusion log Print exclusion counts and proportions at each step
6. Descriptive stats n, mean, sd, se, ci95, median, mad, grouped by condition
7. Assumption tests Shapiro-Wilk + QQ plot + Levene/Mauchly (as needed)
8. Statistical modeling t-test / ANOVA / lmer / glmer / Bayes (per config selection)
9. Effect size Cohen's d / η²p / R² / OR
10. Post-hoc comparisons Estimated marginal means + multiple comparison correction
11. Figure generation Raincloud / individual lines / boxplot / interaction plot → save to disk
12. Environment info Version + package versions
(This is Phase 1 — the generation phase executed after Phase 0 validation passes.)
Priority: questions[].user_choice > decision tree default. If the designer explicitly chose a method (user_choice = method_a or method_b), use that method directly without running the decision tree below. Only use the decision tree when user_choice is unset or empty.
Model Selection Decision Tree
What is design.dvs[].type?
├── continuous (RT/score)
│ ├── design.design_type = within
│ │ ├── specified in questions → use the specified model
│ │ └── not specified → default lmer / MixedLM
│ └── design.design_type = between
│ └── default Welch t-test / oneway.test
│
└── binary (accuracy)
├── any condition accuracy > 90% or < 10%
│ └── force glmer(binomial) / Logit — ANOVA disallowed
└── accuracy between 10-90%
└── recommend glmer/Logit, ANOVA acceptable (note limitation)
Formula validation: Before using model_formula, verify:
- Within-subjects design → formula must include
(1+condition|subject) or a similar random-effects term
- Binary DV → must use glmer/binomial, may not use lmer
- Variable names in the formula must exist in the data columns
Validation failure → use the decision tree default model, output warning with explanation.
Data Aggregation Rules
| Analysis | Aggregation Level |
|---|
| Paired t-test | Subject × Condition means |
| lmer / MixedLM | Trial level (no aggregation) |
| Descriptive statistics | Condition |
| Participant exclusion | Subject |
Defaults for Missing Fields
| Missing Field | Default Behavior |
|---|
cleaning.rt_lower | 150 |
cleaning.rt_upper | 3000 |
cleaning.accuracy_min | 0.6 |
cleaning.trial_exclusion | 2.5 |
cleaning.missing_policy | listwise |
model.contrast | treatment |
model.correction | bonferroni |
output.report_format | RMarkdown (R) / Jupyter (Python) |
output.figures | raincloud + individual |
output.effect_sizes | auto-select based on model type |
When using defaults, output warning: ⚠️ config did not specify {field}, using default {default} | |
Figure Mapping
See psy-ana-designer's plots/ directory (48 detailed figure specifications) and the R ↔ Python mapping table in this document.
| Figure Type | When to Use | Elements |
|---|
| Raincloud | Within-subjects two-group | Violin + boxplot + individual scatter |
| Individual lines | Within-subjects | One line per person + red mean |
| Boxplot + scatter | Multi-group | Boxplot + jitter |
| Interaction plot | Multi-factor | Grouped lines + error bars |
| QQ plot | Normality test | Theoretical quantiles vs actual |
Effect Size Quick Reference
| Method | Metric | Interpretation |
|---|
| t-test | Cohen's d + 95%CI | 0.2 small, 0.5 medium, 0.8 large |
| ANOVA | η²p | 0.01 small, 0.06 medium, 0.14 large |
| Mixed model | Marginal + Conditional R² | Fixed + overall |
| Logistic model | Odds Ratio + 95%CI | OR>1 odds increase |
Multiple Comparison Schemes
| Method | Characteristics |
|---|
| Bonferroni | Most conservative, p × number of comparisons |
| FDR (BH) | Controls false discovery rate, exploratory |
| Tukey HSD | All pairwise comparisons |
| Uncorrected | Only for pre-registered single hypothesis |
Sensitivity Analysis
For each scientific question, compare method A vs B for conclusion consistency. Flag when results are inconsistent and require further investigation.
Report Template
Generate reproducible report: R → RMarkdown/Quarto, Python → Jupyter Notebook. Includes: title, exclusion summary, descriptive statistics, model results, figures, environment info.
R ↔ Python Mapping
| Operation | R | Python |
|---|
| Data import | readr::read_csv() | pandas.read_csv() |
| Filter | filter(col > x) | df[df['col'] > x] |
| Group summary | group_by() %>% summarise() | df.groupby().agg() |
| Pipe | %>% | Chained calls |
| Paired t-test | t.test(y~x, paired=TRUE) | scipy.stats.ttest_rel(a,b) |
| Independent t-test | t.test(y~x, var.equal=FALSE) | scipy.stats.ttest_ind(a,b) |
| Within-subjects ANOVA | afex::aov_ez() | pingouin.rm_anova() |
| Between-subjects ANOVA | oneway.test(y~x) | scipy.stats.f_oneway() |
| Mixed model | lme4::lmer() | statsmodels.MixedLM() |
| Logistic mixed | lme4::glmer(binomial) | statsmodels.Logit() + RE |
| Normality | shapiro.test() | scipy.stats.shapiro() |
| Homogeneity of variance | leveneTest() | scipy.stats.levene() |
| Cohen's d | effectsize::cohens_d() | pingouin.compute_effsize() |
| η² | effectsize::eta_squared() | pingouin.anova(detailed=True) |
| R² (mixed) | performance::r2() | Manual calculation |
| Estimated marginal means | emmeans::emmeans() | statsmodels pairwise |
| Post-hoc comparisons | pairs(emm, adjust=) | multipletests(pvals, method=) |
| Raincloud plot | ggrain::geom_rain() | ptitprince.RainCloud() |
| Save figure | ggsave() | plt.savefig() |
| Seed | set.seed() | np.random.seed() |
| Environment info | sessionInfo() | sys.version + pip freeze |
Routing
Analysis config YAML (input)
│
├── Target=R → r/spec/ + r/mapping/
│ → Generate: analysis.R + report.Rmd → save to output.save_path/
└── Target=Python → python/spec/ + python/mapping/
→ Generate: analysis.py + report.ipynb → save to output.save_path/
│
▼
psy-ana-reviewer (audit)
After generation: Code has been saved to {output.save_path}/.
"Code generation complete. Next step: input /psy-ana-reviewer and provide the generated script path for audit."