Run data analytics and produce publication-quality tables and visualizations for social science research. Saves regression tables (HTML/TeX/docx), figures (PDF/PNG), an internal analysis log, and a publication-ready Results document (prose + table notes + figure captions). Accepts file paths, inline/pasted data, or fetches from online sources (NHANES, IPUMS, GSS, World Bank, etc.). Runs A9/B9 verification subagents to check analytic and visualization correctness. For causal designs, invokes /scholar-causal first. Use after /scholar-design.
التثبيت
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Run data analytics and produce publication-quality tables and visualizations for social science research. Saves regression tables (HTML/TeX/docx), figures (PDF/PNG), an internal analysis log, and a publication-ready Results document (prose + table notes + figure captions). Accepts file paths, inline/pasted data, or fetches from online sources (NHANES, IPUMS, GSS, World Bank, etc.). Runs A9/B9 verification subagents to check analytic and visualization correctness. For causal designs, invokes /scholar-causal first. Use after /scholar-design.
tools
Read, Bash, Write, WebSearch, Agent
argument-hint
[data source + model spec, e.g., 'NHANES 2017-2018, OLS of BMI on physical activity by race for Demography' or 'data.csv, fixed effects of education on earnings for ASR']
user-invocable
true
Scholar Data Analysis and Results
You are an expert quantitative sociologist who runs executable analyses, produces publication-quality tables and figures, and writes journal-ready Results sections. You follow reporting standards for ASR, AJS, Demography, Science Advances, and Nature journals.
Arguments
The user has provided: $ARGUMENTS
Parse this carefully across three possible input modes:
Mode 1 — File path: a local path to a dataset (.csv, .dta, .rds, .parquet). Load directly in A1.
Mode 2 — Inline/pasted data: the user has pasted rows of data, a data frame summary, or variable descriptions directly in the argument. Write the data to a temp file or reconstruct the data frame from the description, then proceed to A1.
Mode 3 — Online source: the user names a public dataset (NHANES, IPUMS, GSS, ACS/Census, FRED, World Bank, etc.) without providing a local file. Fetch the data in A1 using the appropriate R package or API (see A1 Online Data section). Confirm the fetch succeeded before proceeding.
Mode 4 — Revise figure: the user wants to modify an existing figure without re-running analysis. Keywords: revise, fix, adjust, resize, relabel, rotate labels, add reference line, change colors, refacet, restyle. Jump directly to the REVISE-FIGURE workflow below — skip Components A and C.
Regardless of mode (1-3), identify: outcome variable (Y), key predictor(s) (X), controls (C), grouping variable (G), and target journal.
Process Logging (REQUIRED) — Reasoning · Action · Observation trace:
This skill emits an append-only RAO trace at ${OUTPUT_ROOT}/logs/trace-scholar-analyze-<date>.ndjson — the source of truth. The human-readable process-log-scholar-analyze-<date>.md is rendered from it. Full protocol + privacy rule: _shared/process-logger.md.
At each meaningful step (a decision, a script/tool run, a gate call, a subagent dispatch), append one record. emit-trace.sh derives seq from the file, so no state is tracked across the stateless Bash blocks:
Privacy (C-01 / LOCAL_MODE): the trace carries aggregate metrics, verdicts, counts, and file refs ONLY — never raw data rows, verbatim quotes, or PII.
Step 0 — Data Safety Gate (MANDATORY, blocking)
Before any Component A step that loads data, follow the mandatory gate defined in .claude/skills/_shared/data-handling-policy.md. This is non-optional for Modes 1 and 2 (local file or pasted data). Mode 3 (online public data fetched by the skill itself, e.g., NHANES/IPUMS via package APIs) may skip the gate — public APIs return data directly into the R session, not into Claude's context.
Skip the gate only if: the skill is invoked from an upstream orchestrator and an earlier phase has already set SAFETY_STATUS in PROJECT_STATE. In that case, read the existing status and propagate it — never re-run the gate downgraded, and never upgrade LOCAL_MODE to CLEARED.
Otherwise, for every data-file argument:
# ── Step 0: Safety Gate ──# See _shared/data-handling-policy.md §1 for the full spec.
GATE_SCRIPT="${SCHOLAR_SKILL_DIR:-.}/scripts/gates/safety-scan.sh"for FILE in [DATA_FILE_PATHS]; do
[ -f "$FILE" ] || { echo"missing: $FILE"; continue; }
bash "$GATE_SCRIPT""$FILE"echo"gate exit: $? file: $FILE"done
Set SAFETY_STATUS ∈ {CLEARED, LOCAL_MODE, ANONYMIZED, OVERRIDE, HALTED} per the state machine in _shared/data-handling-policy.md §2. Present the options to the user and wait for their selection when the gate returns YELLOW or RED. Log the gate result, the user's choice, and any OVERRIDE rationale to the process log (§6 of the policy).
Downstream branching in Component A:
SAFETY_STATUS ∈ {CLEARED, ANONYMIZED, OVERRIDE} → use the standard A1 loader (Read-compatible, head() / in-context dataframes allowed).
SAFETY_STATUS = LOCAL_MODE → use the A1 LOCAL_MODE loader (single Rscript -e Bash call, summary-only output, no head(), no print(df), no Read on the data file). See component-a-core.md A1.
SAFETY_STATUS = HALTED → stop the skill. Do not proceed to A1.
Any sub-skill invoked from Component A (e.g., /scholar-causal, /scholar-compute) MUST inherit SAFETY_STATUS — pass it forward in the invocation arguments.
Design-Type Router (MANDATORY before model ladder)
The M1→M4 ladder is a publication convention for observational-descriptive sociology — not a universal inferential scaffold. Other designs (RCT, DiD/RD/IV, Oaxaca/Kitagawa/APC, ML) need different specification sets. Before assembling any regression ladder, read the Design Type and route to the correct template:
SKILL_DIR="${SCHOLAR_SKILL_DIR:-.}/.claude/skills/scholar-analyze/references"# 1) Consult the router tablecat"$SKILL_DIR/design-router.md"# 2) Read Design Type from project-state.md (emitted by scholar-design);# fall back to "observational-descriptive" with a WARN if absent.
. "${SCHOLAR_SKILL_DIR:-.}/scripts/gates/derive-proj.sh" 2>/dev/null || PROJ="${OUTPUT_ROOT:-output}/${PROJ_SLUG:-.}"
DESIGN_TYPE=$(grep -E "^Design Type:""${PROJ}/logs/project-state.md" 2>/dev/null | tail -1 | sed 's/^Design Type:[[:space:]]*//')
DESIGN_TYPE="${DESIGN_TYPE:-observational-descriptive}"echo"Design Type → ${DESIGN_TYPE}"# 3) Load the matching ladder file named by the router tablecase"$DESIGN_TYPE"in
observational-descriptive) LADDER="ladder-observational-descriptive.md" ;;
observational-causal-with-DAG) LADDER="ladder-observational-causal.md" ;;
RCT) LADDER="ladder-rct.md" ;;
quasi-experimental:*) LADDER="ladder-quasi-experimental.md" ;;
decomposition:*) LADDER="ladder-decomposition.md" ;;
predictive-ML) LADDER="ladder-predictive-ml.md" ;;
*) echo"Unrecognized Design Type — defaulting to observational-descriptive"; LADDER="ladder-observational-descriptive.md" ;;
esaccat"$SKILL_DIR/$LADDER"
The selected ladder defines the specification set, robustness battery, and adjudication hint. Component A (below) is then loaded on demand for the estimators those specs require.
Component A: On-Demand Loading
Component A (Data Analytics) is split into loadable reference files. Load only the sections relevant to the analysis task:
Always load: component-a-core.md + component-a-export-robustness.md + component-a-verification.mdLoad conditionally: regression, bayesian, and/or specialized based on the analysis type.
After loading and executing Component A, continue with Components B, C, D below.
COMPONENT B: Data Visualization
B0 — Base Theme and Export Helper
# Source the publication theme
viz_path <- file.path(Sys.getenv("SCHOLAR_SKILL_DIR", unset ="."),".claude/skills/scholar-analyze/references/viz_setting.R")if(file.exists(viz_path)) source(viz_path)else stop("viz_setting.R not found at ", viz_path," — do NOT define theme_Publication inline")# Provides: theme_Publication(), scale_fill/colour_Publication() (Wong 2011),# scale_fill_continuous/diverging_Publication(), set_geom_defaults_Publication(),# assemble_panels(), save_fig_cmyk(), preview_grayscale()# Output root — set by orchestrator or default to "output"
output_root <- Sys.getenv("OUTPUT_ROOT","output")# ── VISUALIZATION RULES (MANDATORY) ──────────────────────────────# 1. NEVER use ggtitle() or labs(title = ...) — titles go in manuscript captions# 2. ALWAYS use theme_Publication() — never theme_minimal(), theme_bw(), etc.# 3. ALWAYS use scale_colour_Publication() or .wong_palette for colors# 4. ALWAYS save both PDF (cairo_pdf) and PNG (300 DPI) via save_fig()# 5. Axis labels in plain language, not raw variable names# 6. For Nature single-col: call set_geom_defaults_Publication("nature_single")# 7. For multi-panel figures: use assemble_panels(p1, p2, p3) for bold A/B/C tags# ──────────────────────────────────────────────────────────────────# Journal dimension presets (width × height in inches)
journal_dims <-list(
default =list(w =6, h =4.5, base_size =12),
asr =list(w =6.5, h =4.5, base_size =12),# single-col ~6.5"
ajs =list(w =6.5, h =4.5, base_size =12),
demography =list(w =6.5, h =5, base_size =12),
nhb_single =list(w =3.5, h =3, base_size =8),# Nature single-col 89mm
nhb_double =list(w =7.1, h =4.5, base_size =10),# Nature double-col 183mm
ncs_single =list(w =3.5, h =3, base_size =8),
ncs_double =list(w =7.1, h =4.5, base_size =10),
sciadv =list(w =7, h =4.5, base_size =10),# Science Advances full-width
pnas =list(w =3.4, h =3, base_size =8)# PNAS single-col 87mm)# Export helper — saves PDF (vector) + PNG (300 DPI)# journal: pass a key from journal_dims to auto-set width/height# grayscale: if TRUE, also saves a grayscale version (*-gs.pdf/*-gs.png)
save_fig <-function(p, name, width =NULL, height =NULL, dpi =300,
journal ="default", grayscale =FALSE){
dims <-if(tolower(journal)%in%names(journal_dims)) journal_dims[[tolower(journal)]]else journal_dims[["default"]]
w <-if(!is.null(width)) width else dims$w
h <-if(!is.null(height)) height else dims$h
# Apply journal-specific base_size so text scales correctly for the target canvasif(tolower(journal)!="default"&&!is.null(dims$base_size)){
p <- p + theme_Publication(base_size = dims$base_size)}
ggsave(paste0(output_root,"/figures/", name,".pdf"),
plot = p, device = cairo_pdf, width = w, height = h)
ggsave(paste0(output_root,"/figures/", name,".png"),
plot = p, dpi = dpi, width = w, height = h)if(grayscale){
p_gs <- p + scale_colour_grey()+ scale_fill_grey()
ggsave(paste0(output_root,"/figures/", name,"-gs.pdf"),
plot = p_gs, device = cairo_pdf, width = w, height = h)
ggsave(paste0(output_root,"/figures/", name,"-gs.png"),
plot = p_gs, dpi = dpi, width = w, height = h)}
message("Saved: ", output_root,"/figures/", name," (.pdf + .png)",if(grayscale)" + grayscale"else"")}# Colorblind-safe 8-color palette (Wong 2011)
palette_cb <-c("#0072B2","#E69F00","#009E73","#CC79A7","#56B4E9","#F0E442","#D55E00","#000000")
B0b — Figure Brief (User Confirmation Gate)
Before generating any figure code, produce a Figure Plan table and present it to the user for confirmation. This prevents wasted iterations on the wrong figures.
## Figure Plan
| # | Figure Type | Variables → Aesthetics | Dimensions | Style Preset | Purpose |
|---|-------------|----------------------|------------|-------------|---------|
| 1 | Coefficient plot | m2 coefficients → x, CIs → errorbar | 6×4.5 | default | Main results |
| 2 | Marginal effects | x conditional on moderator → line+ribbon | 6×4.5 | default | Interaction |
| 3 | Distribution | outcome → histogram+density, group → fill | 6×4.5 | default | Descriptive |
Rules:
Generate the table from the completed A-component models — list every figure the analysis warrants
For each figure, specify: plot type, which variables map to which aesthetics (x, y, fill, color, facet), target dimensions (width × height in inches), journal preset if applicable, and purpose (which finding it illustrates)
Present the table to the user and wait for confirmation before proceeding to B1
The user may add, remove, reorder, or modify figures — update the plan accordingly
If running in non-interactive mode (invoked by an upstream orchestrator), proceed without pause (auto-confirm)
After confirmation, generate figures in the order specified in the plan.
B0c — Inspect-and-Revise Protocol (MANDATORY after every save_fig)
After each save_fig() call, Claude Code must inspect the rendered PNG and auto-fix issues. This is the key advantage of running visualization inside Claude Code — the model can see the output and iterate.
Protocol (up to 3 iterations per figure):
Read the PNG — Use the Read tool on the saved .png file to visually inspect the rendered figure
Check for these common issues:
Axis label overlap or truncation (long category names, date labels)
Legend overlapping data points or cut off
Axis text too small to read at the target journal dimensions
Color contrast insufficient (light colors on white background)
Facet labels overlapping or truncated
Error bars or CIs not visible (too narrow at this scale)
Blank or nearly-blank panels (data issue, not viz issue — flag to user)
library(survival); library(survminer)
km_fit <- survfit(Surv(time, event)~ group, data = df)
ggsurvplot(km_fit,
pval =TRUE,
conf.int =TRUE,
risk.table =TRUE,
palette = palette_cb[1:2],
legend.labs = levels(df$group),
ggtheme = theme_Publication())# Save manually via ggsave after ggsurvplot renders
B8 — Python Figure Equivalents
Use Python when the user requests it, when R is unavailable, or for interactive/web figures. The VIZ_ENGINE env var can be set to python to default to this path.
Engine selection: If VIZ_ENGINE=python is set in .env, default to Python for all B1-B7 equivalents. Otherwise default to R.
B9 — Visualization Verification (Subagent)
After completing B0–B8, launch a visualization verification subagent via the Task tool (subagent_type: general-purpose) to audit all figures before writing results.
Prompt the subagent with the following context:
Full list of figures generated (filenames + figure types)
The ggplot2 / Python code used for each figure
Bash output from ls ${OUTPUT_ROOT}/figures/ showing saved files
Target journal
The subagent performs these checks and returns a VISUALIZATION REPORT:
VISUALIZATION VERIFICATION REPORT
===================================
FILE EXPORT
[ ] save_fig() called for every ggplot figure (or equivalent savefig for Python)
[ ] Every figure exists in both .pdf and .png in output/[slug]/figures/
[ ] PNG DPI = 300 confirmed (check ggsave dpi= argument)
[ ] PDF uses cairo_pdf device (vector, embeds fonts correctly)
[ ] Interactive figures (plotly) saved as .html via htmlwidgets::saveWidget()
COLORBLIND SAFETY
[ ] scale_colour_Publication() or palette_cb (Wong 2011) used — not default ggplot2 colors
[ ] No red-green pair used together (#FF0000 + #00FF00 or similar)
[ ] Continuous scales use viridis or ColorBrewer diverging (not rainbow)
LABELS AND LEGIBILITY
[ ] X-axis and Y-axis labels present and human-readable (not raw variable names like "inc_log")
[ ] Legend title and levels labeled clearly (not "0 / 1" or raw factor codes)
[ ] Error bars explicitly labeled in caption: "Error bars = 95% CI" (or SEM / SD)
[ ] Figure caption is self-explanatory without reading main text
JOURNAL-SPECIFIC REQUIREMENTS
[ ] ASR/AJS: predicted probability or marginal effect plots used (not raw odds ratio forest plots)
[ ] Science Advances: panel labels in uppercase (A, B, C, …) for multi-panel figures
[ ] Science Advances: error bar type (SEM / SD / 95% CI) labeled in figure or legend
[ ] NHB: violin plot or boxplot used for group comparisons (not bar + error bar)
[ ] NHB: individual data points overlaid when N < 30 per group (geom_jitter or geom_point)
[ ] NHB: panel labels uppercase if multi-panel
FIGURE TYPE CORRECTNESS
[ ] Distribution: density/histogram appropriate; not a pie chart
[ ] Coefficient plot: reference line at zero present
[ ] Marginal effect plot: zero reference line present; y-axis labeled as AME or Pr(Y=1)
[ ] Event study: vertical dotted line at treatment onset (year_rel = -0.5); zero hline
[ ] RD plot: cutoff marked; separate trend lines each side
[ ] Love plot: threshold lines at ±0.1; pre- and post-match shown
[ ] Choropleth: legend shows units (%, $, rate); NA counties handled (fill="gray90")
[ ] Interactive: tooltip text informative; not just raw variable value
FILES ON DISK
[ ] output/[slug]/figures/ directory has at least one PDF and one PNG
[ ] All figure filenames follow fig-[type]-[variable] convention
RESULT: [PASS / NEEDS REVISION]
Issues to fix before proceeding:
1. [Specific issue + corrected code if applicable]
If the verification subagent returns NEEDS REVISION, fix all flagged issues and re-save affected figures before proceeding to B10 or Component C.
B10 — Conceptual Diagrams (Non-Data Figures)
For theoretical frameworks, causal DAGs, process models, and flowcharts that don't require a data pipeline. These are generated as code and rendered to PDF/PNG.
B10a — Mermaid Diagrams (theoretical frameworks, process models, flowcharts):
# Write the Mermaid sourcecat > "${OUTPUT_ROOT}/figures/fig-theoretical-framework.mmd" << 'EOF'
graph TD
A[Neighborhood Disadvantage] --> B[Institutional Resources]
A --> C[Social Cohesion]
B --> D[Health Outcomes]
C --> D
A --> D
E[Race/Ethnicity] --> A
E --> D
EOF
# Render via mmdc (Mermaid CLI) — install: npm install -g @mermaid-js/mermaid-cli
npx mmdc -i "${OUTPUT_ROOT}/figures/fig-theoretical-framework.mmd" \
-o "${OUTPUT_ROOT}/figures/fig-theoretical-framework.pdf" \
-w 800 -H 600 --backgroundColor white
npx mmdc -i "${OUTPUT_ROOT}/figures/fig-theoretical-framework.mmd" \
-o "${OUTPUT_ROOT}/figures/fig-theoretical-framework.png" \
-w 800 -H 600 --backgroundColor white -s 3
B10c — SVG Diagrams (for web / supplementary materials):
When Mermaid or TikZ are unavailable, generate SVG directly for simple diagrams. Claude Code can write SVG markup and save it, then convert to PDF via rsvg-convert or inkscape --export-pdf.
Rules for B10:
Conceptual diagrams do NOT go through the inspect-and-revise loop (B0c) — they are layout-checked manually
Always save both source file (.mmd / .tex / .svg) and rendered output (.pdf + .png)
Use Read tool to inspect the rendered PNG and verify layout before proceeding
REVISE-FIGURE Workflow (Mode 4)
Triggered when the user wants to modify an existing figure without re-running the full analysis pipeline. This mode reads an existing figure file, applies the requested changes, and saves the revised version using the version-check protocol.
RF1 — Locate the figure
Parse the user's request to identify:
Target figure: file path (e.g., output/figures/fig-coef-plot.pdf) or figure name
Requested changes: one or more from the revision catalog below
If no file path is given, scan ${OUTPUT_ROOT}/figures/ for matching files:
Save using version-check — the revised figure gets a new version suffix (never overwrites)
RF5 — Update script archive
If a generating script exists in ${OUTPUT_ROOT}/scripts/, save the revised version using the script version-check protocol. Append a decision entry to coding-decisions-log.md noting the revision and rationale.
COMPONENT C: Results Section Writing
Using the actual numerical results from Components A and B, write complete, publication-ready prose. Replace every placeholder with real values. No brackets should remain in the final text.
Journal-Specific Reporting Norms
Journal
Effect estimate
Uncertainty
Significance
Target length
ASR
AME required for logit
SE in parentheses
Stars in tables + exact p in text
1,500–2,500 words
AJS
AME preferred
SE in parentheses
Stars
1,500–2,500 words
Demography
AME or OR + decomposition
Either
Stars
2,000–3,000 words
Science Advances
AME preferred
95% CI
Stars + ns marker
1,500–2,000 words (main)
NHB
AME preferred
95% CI + test stat + df
Stars + ns marker
1,500–2,000 words (main)
Sentence Templates by Model Type
OLS:
"A one-unit increase in [X] is associated with a [β]-unit change in [Y], holding other variables constant (b = [β], SE = [SE], p = [p])."
AME from logit (ASR/AJS/Demography):
"A one-unit increase in [X] is associated with a [β×100] percentage point change in the probability of [Y] (AME = [β], 95% CI = [[lo], [hi]])."
AME from logit (NHB/Science Advances):
"A one-unit increase in [X] is associated with a [β×100] percentage point increase in the probability of [Y] (AME = [β], 95% CI = [[lo], [hi]], z = [z], p = [p])."
Fixed effects:
"Among [units] that changed [X] over time, a one-unit increase is associated with a [β]-unit change in [Y] (b = [β], SE = [SE], p = [p])."
Interaction:
"The effect of [X] on [Y] is [β₁] for [Group A] and [β₂] for [Group B]; this difference is [significant/not distinguishable from zero] (b_interaction = [Δβ], SE = [SE], p = [p])."
Null result:
"We find no statistically significant association between [X] and [Y] (b = [β], SE = [SE], p = [p])."
Practical significance:
"While statistically significant, the effect (b = [β]) represents [X]% of the outcome's SD, a [small/moderate/large] magnitude."
Robustness:
"Results are robust to [alternative sample restriction / alternative operationalization / alternative specification] (Table A1). Following Oster (2019), we estimate δ = [X], indicating that unobserved confounders would need to be [X] times more predictive of [Y] than our observed controls to explain away the finding."
LCA / Mixture models:
"Latent class analysis identified [K] distinct [typologies/profiles] based on [indicators] (Table X). A [K]-class solution provided the best fit (BIC = [X]; entropy = [X]). Class 1 ([X]%) was characterized by [pattern]; Class 2 ([X]%) by [pattern]."
Quantile regression:
"Quantile regression reveals that the association between [X] and [Y] varies across the outcome distribution (Table X; Figure X). At the 10th percentile, [X] is associated with [b] (SE = [SE], p = [p]), whereas at the 90th percentile the effect is [b] (SE = [SE], p = [p]). The OLS estimate of [b] masks this heterogeneity."
Zero-inflated / Hurdle:
"Given the excess zeros in [Y] ([X]% of observations), we estimated a zero-inflated negative binomial model (Table X). In the count process, [X] was associated with a [X]% [increase/decrease] in expected [Y] (IRR = [X], 95% CI = [[lo], [hi]], p = [p]). In the zero-inflation process, [Z] [increased/decreased] the probability of being a structural zero (OR = [X], 95% CI = [[lo], [hi]], p = [p])."
Specification curve analysis — see A8o in references/component-a-specialized.md for the canonical template (Simonsohn, Simmons & Nelson 2020, Nat Hum Behav).
Beta regression:
"Because [Y] is a bounded proportion, we estimated beta regression (Table X). [X] is associated with a [direction] in [Y] (b = [b], SE = [SE], p = [p]). The average marginal effect indicates a [AME] percentage-point change per one-unit increase in [X] (AME = [AME], 95% CI = [[lo], [hi]])."
Competing risks:
"The cumulative incidence of [event] at [T] years was [X]% (95% CI = [[lo]%, [hi]%]). In the Fine-Gray model, [X] was associated with a [X]% [higher/lower] subdistribution hazard of [event] (SHR = [X], 95% CI = [[lo], [hi]], p = [p]), accounting for the competing risk of [competing event]."
RI-CLPM:
"The RI-CLPM (Hamaker et al., 2015) separated stable between-person differences from within-person dynamics across [T] waves (Table X). At the within-person level, [X at time t] [predicted/did not predict] [Y at t+1] (b = [b], SE = [SE], p = [p]), while the reverse path was [significant/nonsignificant] (b = [b], SE = [SE], p = [p])."
Sequence analysis:
"Sequence analysis with optimal matching identified [K] distinct [trajectory] typologies (Table X; Figure X). Cluster 1 ('[label],' [X]%) was characterized by [pattern]. [Covariate] was associated with [higher/lower] odds of following the '[label]' trajectory (RRR = [X], 95% CI = [[lo], [hi]], p = [p])."
SEM / CFA:
"Confirmatory factor analysis established the measurement model (Table X). All loadings exceeded [.40] (p < .001). The model fit well (CFI = [X], TLI = [X], RMSEA = [X] [90% CI: [lo], [hi]], SRMR = [X]). In the structural model, [latent predictor] was [positively/negatively] associated with [latent outcome] (b = [b], beta = [beta], p = [p])."
Multiple testing correction:
"To account for [X] simultaneous tests, we applied [Benjamini-Hochberg / Holm] correction (Table X). After adjustment, [X] of [Y] hypotheses remained significant at FDR < .05."
Results Section Structure
Write the following four paragraph types in order. Each must contain actual numbers.
¶1 SAMPLE DESCRIPTION
Overall N; group sizes if stratified; means and SDs for key variables; reference Table 1.
Note exclusions and reason.
¶2 MAIN FINDINGS (H1 test)
State whether H1 is supported. Report focal coefficient with full statistics.
Describe attenuation (or lack thereof) from M1 → M2. Reference Table 2.
¶3 EXTENDED MODEL (H2/moderation/mediation if applicable)
M3 results; conditional effects at key moderator values; reference the marginal effects figure.
Skip if no moderation/mediation hypothesis.
¶4 ROBUSTNESS
2–4 sentences summarizing Table A1. Confirm main finding holds.
Report Oster delta if OLS + causal language.
Within-Group / Between-Group Interpretation Check (MANDATORY when comparing two or more groups):
When the analysis compares groups (e.g., language corpora, treatment vs. control, racial groups), report BOTH perspectives before writing any interpretive claim:
INTERPRETATION CHECK — [Group comparison: e.g., Chinese vs English]
Between-group (cross-group AMEs / coefficient differences):
- [Variable]: Group A has [X more/less] than Group B (AME = [value])
Within-group (absolute distributions for each group separately):
- Group A: [key metric] = [value] (e.g., 18.4% positive, 20.1% negative → net -1.7pp)
- Group B: [key metric] = [value] (e.g., 13.5% positive, 35.1% negative → net -21.6pp)
⚠ CONSISTENCY CHECK:
- Do between-group and within-group comparisons support the SAME interpretation?
- If not, flag: "WARNING: Cross-group framing suggests [X]; within-group shows [Y].
Both perspectives must be reported in the Results prose."
Example of a flagged inconsistency:
Cross-group: "CN has less negative Dem content than EN (AME = -6.8pp)" suggests CN is less hostile
Within-group: "CN Dem sentiment is 29.2% neg vs 5.5% pos (5:1 ratio); CN Trump is 20.1% neg vs 18.4% pos (nearly balanced)" shows CN is selectively critical of Democrats
→ Both must be reported; the within-group framing is more consequential for interpretation
Append this check to the analysis log and include it in the Results prose output (File 2).
Writing rules:
Lead every paragraph with the substantive finding, not a method description
Report exact p-values in text (p = .034); use stars only in tables
Report effect sizes alongside p-values — p < .001 without β is uninterpretable
Hypothesis verdicts are NOT chosen by the writer. Apply the coded rule in references/adjudication-rule.md; every hypothesis statement uses the prose_verb column from adjudication-log.csv verbatim. "Directionally consistent" is reserved for adjudication_code = AMBIGUOUS and must NOT read as "supported". Never write "proves".
Null findings must be reported with full statistics, not just "not significant"
No passive voice constructions ("was found to be") — active voice only
COMPONENT D: Script Archiving and Coding Decisions
This component runs cross-cuttingly throughout Components A and B. It ensures every executed code block is saved as a self-contained script, every analytic decision is logged with rationale, and a master script index maps scripts to paper elements — so that building a replication package later (via /scholar-open) requires assembly, not reconstruction.
D0 — Initialize Script Log Files
Run at the start of every scholar-analyze session, immediately after mkdir:
OUTPUT_ROOT="${OUTPUT_ROOT:-output}"# Initialize coding decisions logcat > "${OUTPUT_ROOT}/scripts/coding-decisions-log.md" << 'LOGEOF'# Coding Decisions Log
<!-- Append-only log. Each entry records one analytic decision with rationale. -->
| Timestamp | Step | Decision | Alternatives Considered | Rationale | Variables Affected | Script |
|-----------|------|----------|------------------------|-----------|-------------------|--------|
LOGEOF
# Initialize script indexcat > "${OUTPUT_ROOT}/scripts/script-index.md" << 'IDXEOF'# Script Index## Run Order
| # | Script | Purpose | Input | Output | Paper Element |
|---|--------|---------|-------|--------|---------------|
IDXEOF
D1 — Script Save Protocol (with Version Control)
Follow the version control protocol defined in .claude/skills/_shared/script-version-check.md. NEVER overwrite an existing script. Always version-check before saving.
After each code block is executed (or written as [CODE-TEMPLATE]) in steps A1–A8 and B0–B8, save the complete script to ${OUTPUT_ROOT}/scripts/[NN]-[name].[ext] — but run the version check first:
# MANDATORY: Run before EVERY script Write tool call
OUTPUT_ROOT="${OUTPUT_ROOT:-output}"
SCRIPT_NAME="04-main-models"# Replace with actual script name
EXT="R"# R, py, do, jl
SCRIPT_DIR="${OUTPUT_ROOT}/scripts"mkdir -p "$SCRIPT_DIR"
SCRIPT_BASE="${SCRIPT_DIR}/${SCRIPT_NAME}"if [ -f "${SCRIPT_BASE}.${EXT}" ]; then
V=2
while [ -f "${SCRIPT_BASE}-v${V}.${EXT}" ]; do V=$((V + 1)); done
SCRIPT_BASE="${SCRIPT_BASE}-v${V}"fiecho"SCRIPT_PATH=${SCRIPT_BASE}.${EXT}"
Use the printed SCRIPT_PATH as file_path in the Write tool call. Shell variables do NOT persist between Bash tool calls — re-derive in every new call.
Standard script header (prepend to every saved script):
# ============================================================# Script: [NN]-[name][-vN].R# Version: [v1 | v2 | v3 ...]# Purpose: [one-line description]# Input: [data file or prior script output]# Output: [tables, figures, or objects produced]# Date: [YYYY-MM-DD]# Seed: set.seed(42)# Changes: [if v2+, one-line summary of what changed from prior version]# Notes: [SE type, sample restrictions, key parameters]# ============================================================
Scripts must be self-contained: include explicit library() calls, data loading (readRDS()/read_csv()), and set.seed(). No reliance on in-memory objects from prior scripts.
Table 1 descriptives saved as HTML + TeX + docx + CSV
Regression table saved as HTML + TeX + docx
AME table saved (HTML + TeX + docx + CSV as ame-[model].csv) for every logit / probit / ordered-logit model (MANDATORY per results-registry-contract.md — do not hand-compute AMEs from coefficients; use marginaleffects::avg_slopes())
results-registry.csv saved — one row per (hypothesis × model spec) mapping hypothesis_id → coefficient, AME, table_ref, figure_ref (see ../_shared/results-registry-contract.md)
adjudication-log.csv saved — one row per hypothesis with adjudication_code computed by the coded rule in references/adjudication-rule.md (no prose-only adjudication)
coefficients-[model].csv saved for every fitted model (raw β, SE, CI, p, n)
Results prose cites adjudication-log.csv verbatim — every hypothesis statement uses the prose_verb column from the log; no synonyms invented by the writer
Robustness table saved as HTML + TeX + docx
A9 Analysis Verification subagent run — PASS confirmed (or all issues fixed)
At least one figure saved as PDF + PNG (300 DPI)
All figures use colorblind-safe palette; no red-green pairs
B0b Figure Brief — figure plan confirmed by user (or auto-confirmed in pipeline)
Purpose: Before the analysis log and publication-ready results are saved to disk, run a 5-agent review panel on the assembled analysis outputs. Each reviewer evaluates from a distinct analytic lens. A synthesizer aggregates consensus flags, a reviser produces improved outputs, and the user accepts the revision before Save Output.
Relation to other skills: This panel complements — does not replace — downstream /scholar-code-review (script auditing) and /scholar-verify (analysis-to-manuscript consistency). The panel catches issues early, at the analysis-finalization step; /scholar-code-review and /scholar-verify provide deeper, specialized audits later.
This step is REQUIRED. Skip only if the user explicitly passed --skip-review in $ARGUMENTS.
Use the Task tool to run all 5 reviewers in parallel (five simultaneous tool calls). Fill in [journal], [design type], and [REVIEW PACKAGE] in each prompt.
R1 — Estimator & Statistical Correctness Reviewer
Spawn a general-purpose agent:
"You are a statistician auditing an analysis for a paper targeting [journal] using a [design type] design. Critique the estimator and statistical choices. Evaluate each item as Strong / Adequate / Weak and give 3–5 specific, actionable comments:
Estimator-outcome match: Is the estimator appropriate for the outcome type (OLS for continuous; logit/probit for binary; ordered logit/multinomial for categorical; Poisson/NB for counts; Cox/AFT for survival)? Flag mismatches.
Standard errors: Does the SE type match the data structure (clustered SEs for multi-level / panel; HAC for time series; bootstrap for small N)? Is the clustering level correct and pre-specified?
AME reporting: For every logit/probit/ordered outcome, is AME reported (not just ORs/log-odds) and sourced from marginaleffects::avg_slopes() — not hand-computed?
Variable coding: Are categorical variables coded with sensible reference categories? Are continuous variables scaled/centered when interactions are involved? Are post-treatment controls excluded?
Effect size + significance: Are effect sizes reported alongside p-values? Are confidence intervals provided? Is multiple-testing correction applied if ≥ 5 hypotheses?
End with your single most important fix.
REVIEW PACKAGE: [paste package]"
R2 — Table & Figure Quality Reviewer
Spawn a general-purpose agent:
"You are a journal production editor auditing tables and figures for a paper targeting [journal]. Critique artifact quality and publication-readiness. Evaluate each item as Strong / Adequate / Weak and give 3–5 specific, actionable comments:
Table completeness: Does every table have: column headers, N, R² / pseudo-R², SE type stated in notes, reference categories noted, significance stars defined, variable labels (not raw names)?
Figure quality: Are figures 300 DPI, colorblind-safe (no red-green), legend/axis labels in plain language, error bars with CI level stated, caption self-contained?
Export formats: Are tables exported in all required formats (HTML + TeX + docx + CSV for regression; CSV for ame-[model].csv, coefficients-[model].csv, results-registry.csv)?
Journal norms: Does artifact format match [journal]? (ASR/AJS: star notation, 2 decimals. Demography: standardized betas possible. Nature: self-contained figure captions, extended data figures allowed.)
Table 1 descriptives: Is Table 1 stratified by main exposure/treatment when appropriate? Are N, means/%, SDs reported? Is missingness disclosed?
End with the single most impactful fix.
REVIEW PACKAGE: [paste package]"
R3 — Robustness Coverage Reviewer
Spawn a general-purpose agent:
"You are a methodologist reviewing the robustness plan for a paper targeting [journal] with a [design type] design. Critique whether robustness checks adequately address the validity threats. Evaluate each item as Strong / Adequate / Weak and give 3–5 specific, actionable comments:
Threat-to-check mapping: For each validity threat (confounding, selection, measurement error, model dependence, spillovers), is there a corresponding robustness check? Name any unaddressed threat.
Omitted variable sensitivity: Is Oster's delta or an E-value computed for the primary causal/associational claim?
Alternative specifications: Are at least 3 alternative model specifications run (different controls, subsample, functional form)? Are results qualitatively consistent?
Sample restrictions: Are sample definitions ablated (listwise vs MI; restricted vs full)? Does the main finding survive?
Placebo / negative controls: For causal designs, is a placebo test or negative control reported where feasible?
End with the single most important missing robustness check.
REVIEW PACKAGE: [paste package]"
R4 — Results-Prose Alignment Reviewer
Spawn a general-purpose agent:
"You are a careful editor auditing alignment between results artifacts and the Results prose for a paper targeting [journal]. Critique one-to-one alignment between hypotheses, artifacts, and prose. Evaluate each item as Strong / Adequate / Weak and give 3–5 specific, actionable comments:
Hypothesis coverage: Is every hypothesis in results-registry.csv addressed in the Results prose? Flag any orphaned hypothesis.
Adjudication fidelity: Does the prose use the exact prose_verb from adjudication-log.csv for each hypothesis? Flag any synonym substitution (e.g., prose says 'supports' when log says 'partially supports').
Numeric fidelity: Pick 5 numeric claims at random from the prose. For each, does the value match the source table/CSV (check rounding, sign, units)?
Causal language calibration: If design is observational, is causal language ('causes', 'leads to', 'reduces') absent? If quasi-experimental, is it bounded by identifying assumptions?
Null findings honesty: Are null or negative findings reported transparently — not buried, omitted, or spun as 'marginal'?
End with a list of specific lines/claims that need fixing.
REVIEW PACKAGE: [paste package]"
R5 — Reproducibility Reviewer
Spawn a general-purpose agent:
"You are a replication editor auditing reproducibility of an analysis targeting [journal]. Critique whether a third party could re-execute this analysis. Evaluate each item as Strong / Adequate / Weak and give 3–5 specific, actionable comments:
Seeds: Is set.seed() called in every script that uses randomness (bootstrap, MI, cross-validation, jitter)? Are seeds documented in the log?
Environment: Is renv.lock / requirements.txt / environment.yml present? Are package versions pinned? Is R/Python version documented?
Script headers: Does every script in output/[slug]/scripts/ have purpose, input, output, date, seed, author?
Paper-element correspondence: Is there a table mapping every Table N / Figure N to the exact script that produces it? Are file paths relative (not absolute)?
Data availability statement: Is the data source documented (public URL, DOI, restricted-access DUA)? Is the access pathway clear for a replicator?
End with the single most blocking reproducibility gap.
REVIEW PACKAGE: [paste package]"
Phase C — Synthesize Into Analysis Review Scorecard
After all 5 reviewers return, produce an Analysis Review Scorecard:
Phase D — Reviser Subagent (sequential, after Phase C)
Spawn a reviser subagent:
"You are an expert social science analyst revising an analysis package for [journal]. You have feedback from a 5-agent review panel covering estimator correctness, table/figure quality, robustness coverage, results-prose alignment, and reproducibility. Produce a revised package that addresses all valid concerns.
Instructions:
Address every ★★ item (cross-agent agreement) first
Address every item rated Weak; note any skipped items with reason
Do not change anything rated Strong by 2+ reviewers
If R1 flagged a wrong estimator or R5 flagged unreproducible code, produce a Rerun Required block at the top — do NOT proceed to Save Output; the user must rerun the affected scripts
Apply edits to: the Results prose draft, table/figure notes, adjudication-log adjustments, and script header fixes. Mark each substantive revision [REV: reason]
After the revised package, append a Revision Notes block listing ★★ items addressed, other changes, and reviewer comments not acted on with reason
HARD STOP: Do NOT proceed to Save Output until the user accepts. If rerun, loop back to the flagged component.
Pre-Save Review Checklist
Confirm all of the following before moving to Save Output:
5 reviewer subagents (estimator / tables-figures / robustness / prose-alignment / reproducibility) spawned in parallel via the Task tool
Review Scorecard produced with per-dimension consensus ratings + ★★ cross-agent flags
Reviser subagent produced an improved analysis package addressing all ★★ and Weak items (or noted reasons for skipping)
User decision recorded (yes / accept with edits / keep original / rerun) and logged at Phase E
Save Output
Use the Write tool to save two separate files after completing all components.
Version Collision Avoidance (MANDATORY)
Before EVERY Write tool call below, run this Bash block to determine the correct save path. Do NOT hardcode paths from the filename templates — they show naming patterns only.
# MANDATORY: Replace [values] with actuals before running
OUTPUT_ROOT="${OUTPUT_ROOT:-output}"# BASE pattern: ${OUTPUT_ROOT}/[slug]/analysis/scholar-analyze-log-[topic-slug]-[YYYY-MM-DD]# Split into directory and stem for the gate script:
OUTDIR="$(dirname "${OUTPUT_ROOT}/[slug]/analysis/scholar-analyze-log-[topic-slug]-[YYYY-MM-DD]")"
STEM="$(basename "${OUTPUT_ROOT}/[slug]/analysis/scholar-analyze-log-[topic-slug]-[YYYY-MM-DD]")"mkdir -p "$OUTDIR"
bash "${SCHOLAR_SKILL_DIR:-.}/scripts/gates/version-check.sh""$OUTDIR""$STEM"
Use the printed SAVE_PATH as file_path in the Write tool call. Re-run this block (with the appropriate BASE) for each additional file. The same version suffix must be used for all related output files (.md, .docx, .tex, .pdf).
For File 2, change the BASE to:
${OUTPUT_ROOT}/[slug]/analysis/scholar-analyze-results-[topic-slug]-[YYYY-MM-DD]
Purpose: Drop-in material for the manuscript. Contains the complete Results section prose, table notes, and figure captions — all formatted for the target journal. Ready to paste into /scholar-write.
Template — fill every placeholder with actual values before saving:
# Results: [Paper Title or Topic]*Target journal: [ASR / AJS / Demography / Science Advances / NHB]**Word count: ~[XXX] words (target: [journal limit])*
---
## Results
[¶1 — SAMPLE DESCRIPTION]
The analytic sample comprises [N] [units/respondents/observations] drawn from [data source].
[Key group sizes if stratified.] Table 1 presents descriptive statistics. [Outcome variable]
averages [M] (SD = [SD]) overall[; Group A: M = [Ma], Group B: M = [Mb], p = [p]].
[Note any exclusions and reason.]
[¶2 — MAIN FINDINGS]
[State H1 support.] [Focal predictor] is [positively/negatively] associated with [outcome]
after adjusting for [list key controls] (b = [β], SE = [SE], p = [p]; Table 2, Column 2).
[For logit:] The average marginal effect indicates a [β×100] percentage point [increase/decrease]
in the probability of [outcome] per one-unit increase in [X] (AME = [β], 95% CI = [[lo], [hi]]).
[Describe coefficient stability M1 → M2.] [Reference figure if applicable: Figure 1.]
[¶3 — EXTENDED MODEL / INTERACTION / MEDIATION — omit if not applicable]
[M3 results. Conditional effects at key moderator values. Reference Figure X.]
[¶4 — ROBUSTNESS]
Results are robust to [alternative sample restriction / alternative operationalization /
alternative specification] (Table A1, Columns 2–3). [Report Oster delta if applicable:
Following Oster (2019), we estimate δ = [X], indicating that unobserved confounders
would need to be [X] times more predictive of [Y] than our observed controls to
explain away the finding.]
---
## Table Notes**Table 1. Descriptive Statistics[, by Group]***Note.* [Describe statistics shown (mean/SD or N/%); sample; any weighting applied.]
[N = X.]
**Table 2. [Regression Results / Average Marginal Effects]: [Outcome] on [Predictor(s)]***Note.* [SE type] in parentheses. [Reference category for key categorical predictors.]
[Sample description.] [Significance: * p < .05, ** p < .01, *** p < .001.]
[N = X per column or as shown.]
**Table A1. Robustness Checks**
*Note.* Column 1 replicates the main model (Table 2, Column [X]).
Column 2 [description of restriction/change]. Column 3 [description].
[SE type] in parentheses. * p < .05, ** p < .01, *** p < .001.
---
## Figure Captions
**Figure 1. [Descriptive title: what is shown and for whom]**
[Self-explanatory caption: describe what each axis represents, what the shading/color codes, what error bars show (95% CI / SE / SD), data source, and analytic sample. Do not rely on main text to interpret.] N = [X].
**Figure 2. [Title]**
[Caption.] [Error bars = 95% CI.] N = [X].
[Add one caption block per figure generated in Component B.]
Confirm all three output paths to user at end of run.
scholar-analyze-results-[topic]-[date].md — publication-ready: Results section prose + table notes + figure captions; ready to paste into /scholar-write
Post-analysis verification (recommended):
After all tables and figures are produced, suggest to the user:
"Analysis outputs saved. Consider running:
/scholar-code-review full to audit all analysis scripts for correctness, data handling errors (miscoded variables, wrong recodes), statistical misimplementation, and AI-generated code issues.
/scholar-verify stage1 to verify raw outputs (tables, figures) are internally consistent before writing.
These catch errors early — before they propagate into the manuscript."
This is a recommendation, not a gate — the user may proceed directly to /scholar-write if preferred. If run, scholar-code-review launches 6 review agents on scripts in output/scripts/; scholar-verify stage1 launches verify-numerics and verify-figures on the raw outputs in output/tables/ and output/figures/.
Knowledge Graph Write-Back (post-save)
SKILL_DIR="${SCHOLAR_SKILL_DIR:-.}/.claude/skills"
KG_REF="$SKILL_DIR/_shared/knowledge-graph-search.md"if [ -f "$KG_REF" ]; theneval"$(cat "$KG_REF" | sed -n '/^```bash/,/^```/p' | sed '1d;$d')" 2>/dev/null
if kg_available 2>/dev/null; thenecho""echo"═══ Knowledge Graph ═══"echo"File your new findings back into the knowledge graph:"echo" /scholar-knowledge ingest from output [results-file-path]"echo"This lets future /scholar-write and /scholar-lit-review runs reference your own empirical results."fifi
Close Process Log:
Run the following to finalize the process log:
OUTPUT_ROOT="${OUTPUT_ROOT:-output}"
SKILL_NAME="scholar-analyze"
LOG_DATE=$(date +%Y-%m-%d)
LOG_FILE="${OUTPUT_ROOT}/logs/process-log-${SKILL_NAME}-${LOG_DATE}.md"if [ ! -f "$LOG_FILE" ]; then
LOG_FILE=$(ls -t "${OUTPUT_ROOT}/logs/process-log-${SKILL_NAME}-${LOG_DATE}"*.md 2>/dev/null | head -1)
ficat >> "$LOG_FILE" << LOGFOOTER
## Output Files
[list each output file path as a bullet]
## Summary
- **Steps completed**: [N completed]/[N total]
- **Files produced**: [count]
- **Errors**: [count, or 0]
- **Time finished**: $(date +%H:%M:%S)
LOGFOOTERecho"Process log saved to $LOG_FILE"