Data Scientist Skill
SkillMediaData science methodology and method-selection routing for quantitative research. Covers EDA, data validation, descriptive analysis, causal inference (IV, DiD, RD, synthetic control), clustering/PCA/UMAP, supervised ML, geospatial analysis, network analysis, and visualization design. Contains the canonical method-to-library routing tree, routed by execution language — Python: statsmodels (OLS/GLM/time series), pyfixest (FE/DiD), linearmodels (RE/GMM/SUR), svy (complex surveys), scikit-learn (clustering/prediction ML), geopandas (spatial), igraph (network analysis); R: r-stats (OLS/GLM/time series), fixest (FE/DiD), plm (panel/RE/IV), survey-r (complex surveys), tidymodels (ML), sf-terra (spatial), igraph-r (network analysis). Load the routed tool-specific skill before giving tool-specific advice or writing code — library skills encode environment constraints and curated caveats absent from general knowledge.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Data Scientist Skill skill
What this skill tells your AI
The instructions your AI receives, as published by daaf-contribution-community/daaf in .claude/skills/data-scientist/SKILL.md and read by ahel’s review.
Rigorous data science methodology and mindset for quantitative research in Python or R. Covers EDA, data validation, transformation verification, documentation standards, visualization design, descriptive analysis, statistical modeling, causal inference method selection (IV, DiD, RD, synthetic control), unsupervised analysis (clustering, PCA, UMAP), supervised ML methodology (prediction vs. inference, cross-validation, model interpretation, fairness), geospatial analysis, and network analysis (centrality, community detection, bipartite graphs). Provides methodology decisions and analytical approach guidance. Load the routed, language-appropriate tool-specific skill (Python: polars, statsmodels, plotnine, pyfixest, scikit-learn, geopandas, igraph; R: tidyverse, r-stats, ggplot2, fixest, tidymodels, sf-terra, igraph-r; etc.) before giving tool-specific advice or writing code — library skills encode environment-specific constraints and curated caveats that general knowledge lacks or gets wrong. Use for any data analysis, exploration, transformation, or modeling task — especially when choosing methods, checking assumptions, or structuring an analysis.
Establishes a rigorous, methodical approach to data science work. This skill is about how to think and work, not specific tools. The moment a specific tool enters the conversation — in advice and brainstorming as much as in code — load its specialized skill (Python: polars, plotnine, plotly, marimo; R: tidyverse, ggplot2, plotly-r, quarto; etc.): those skills know this environment's tooling in ways general knowledge does not.
Core Principles - NON-NEGOTIABLE
These five principles must guide ALL data science work. They are not optional.
Principle 1: Data Robustness First
ALWAYS check data before operating on it.
Before ANY analysis or transformation:
- Check shape, types, and memory usage
- Examine value distributions and ranges
- Identify and characterize missing values (count, percentage, pattern)
- Understand what uniquely identifies each row (granularity)
- Look for outliers and anomalies
Be VERBOSE about what you're checking and what you find. Never assume data is clean.
Python:
# ALWAYS start with this pattern
print(f"Shape: {df.shape}")
print(f"Columns: {df.columns.to_list()}")
print(f"Types:\n{df.dtypes}")
print(f"Null counts:\n{df.null_count()}")
print(f"Sample:\n{df.sample(5)}")
R:
# ALWAYS start with this pattern
cat("Shape:", nrow(df), "x", ncol(df), "\n")
cat("Columns:", paste(names(df), collapse = ", "), "\n")
str(df)
cat("Null counts:\n")
print(colSums(is.na(df)))
cat("Sample:\n")
print(df[sample(nrow(df), 5), ])
This principle applies only when you are conducting actual data work. Do NOT conduct net new analyses or data inspections when tasked with compiling past work (e.g., analytic notebook creation), or synthesizing prior analyses into a report (e.g., final report writing).
Principle 2: Documentation First
ALWAYS understand or create data documentation.
Before analysis:
- Seek data dictionaries, schemas, or documentation
- Understand where data comes from (provenance)
- Learn collection methods and their implications
- Identify known quality issues or caveats
- Clarify what each column means in business context
If documentation doesn't exist, CREATE IT as you learn about the data.
Principle 3: Verify Every Operation
NEVER assume a transformation worked correctly.
For EVERY data operation:
- Check row counts before and after
- Examine random samples of affected rows
- Validate that expected changes occurred
- Confirm no unintended side effects
- Document what you checked and what you found
Python:
# Before transformation
print(f"Before: {len(df)} rows, columns: {df.columns.to_list()}")
sample_before = df.filter(pl.col("id").is_in([1, 42, 100]))
# After transformation
print(f"After: {len(result)} rows, columns: {result.columns.to_list()}")
sample_after = result.filter(pl.col("id").is_in([1, 42, 100]))
print(f"Sample comparison:\nBefore:\n{sample_before}\nAfter:\n{sample_after}")
R:
# Before transformation
cat("Before:", nrow(df), "rows, columns:", paste(names(df), collapse = ", "), "\n")
sample_before <- df |> dplyr::filter(id %in% c(1, 42, 100))
# After transformation
cat("After:", nrow(result), "rows, columns:", paste(names(result), collapse = ", "), "\n")
sample_after <- result |> dplyr::filter(id %in% c(1, 42, 100))
cat("Sample comparison:\nBefore:\n")
print(sample_before)
cat("After:\n")
print(sample_after)
Principle 4: Thorough Code Documentation (ENFORCED)
Write extensive comments explaining your reasoning. This is MANDATORY, not optional.
In research workflows, follow the Inline Audit Trail (IAT) standard (see agent_reference/INLINE_AUDIT_TRAIL.md). The IAT standard is enforced during QA review — scripts with sparse documentation receive WARNING findings.
Every code block should explain:
- WHAT you're trying to accomplish (the goal) → IAT Type 2: Intent Comment
- WHY you chose this approach (the reasoning) → IAT Type 3: Reasoning Comment
- WHAT assumptions you're making (the dependencies) → IAT Type 4: Assumption Comment
For tests and validations, explain:
- What behavior you're checking
- What would indicate success vs. failure
- Why this check matters
Principle 5: Focus on Research Questions
Balance rigor with usefulness.
Always consider:
- What question are we actually answering?
- What level of rigor does this decision require?
- Are there multiple valid approaches with different tradeoffs?
- Should I check with the user before proceeding?
CHECK IN with users when:
- Multiple valid methodologies exist
- Tradeoffs between precision and practicality arise
- Findings are surprising or counterintuitive
- Scope might need adjustment
Language Routing
This skill routes to language-specific library skills based on the execution language set in CLAUDE.md § User Preferences and propagated in the agent's prompt. When no language is specified, default to Python.
| Method | Python Skill | R Skill |
|---|---|---|
| Data manipulation | polars | tidyverse |
| Static visualization | plotnine | ggplot2 |
| Interactive visualization | plotly | plotly-r |
| Fixed effects / DiD | pyfixest | fixest |
| OLS / GLM / time series | statsmodels | r-stats |
| Panel / RE / IV / system | linearmodels | plm |
| Complex survey statistics | svy | survey-r |
| ML / clustering / PCA | scikit-learn | tidymodels |
| Geospatial | geopandas | sf-terra |
| Network analysis | igraph | igraph-r |
| Table formatting | great-tables | gt |
| Notebook | marimo | quarto |
All decision trees below use Python skill names as the primary label, with the R
counterpart noted inline as (Python)/(R) pairs. When the execution language is
R, substitute the R skill from this table. Time-series estimation routes to
statsmodels in Python and r-stats in R (see its references/time-series.md).
Related Skills - When to Load
Core Workflow Skills (Load Together):
polars(R:tidyverse) - Required for DataFrame operations; data-scientist provides methodology, polars/tidyverse provides syntaxmarimo(R:quarto) - Required for creating validated notebooks; data-scientist defines validation patterns, marimo/quarto provides implementation
For Data Analysis Workflows:
In the research pipeline, data-scientist methodology is applied within the file-first execution pattern:
- Write script files FIRST (to
scripts/stage{N}_{type}/) as.py(Python) or.R(R) - Execute via Bash with automatic output capture wrapper script
- Validation results get automatically embedded in scripts as comments
- Marimo (Python) or Quarto (R) notebook assembles validated scripts for interactive review
Closely read agent_reference/SCRIPT_EXECUTION_REFERENCE.md for the mandatory file-first execution protocol covering complete code file writing, output capture, and file versioning rules.
Load for Specific Needs:
What task are you performing?
├─ Data visualization (any kind)
│ └─ Stage 8.2 — FIRST read visualization reference files below:
│ ├─ ./references/visualization-design.md (chart selection, encoding, emphasis)
│ └─ ./references/visualization-execution.md (color, labeling, accessibility, export)
│ THEN load the tool-specific skill:
│ ├─ Static plots → Load `plotnine` skill (Python) or `ggplot2` skill (R)
│ └─ Interactive plots → Load `plotly` skill (Python) or `plotly-r` skill (R)
├─ Descriptive analysis (subgroups, distributions, decompositions, trends)
│ └─ Stage 8.1 — FIRST read ./references/descriptive-analysis.md
│ THEN load the `polars` skill (Python) or `tidyverse` skill (R) (some methods
│ may also need `statsmodels`/`r-stats` for weighted SEs/formal tests or
│ `pyfixest`/`fixest` for descriptive FE regressions)
├─ Statistical modeling (regression, robustness checks)
│ └─ Stage 8.1 — FIRST read ./references/statistical-modeling.md
│ THEN load library skill:
│ ├─ Standard regression (OLS, logistic, GLM) → Load `statsmodels` skill (Python) or `r-stats` skill (R)
│ │ (Note: for OLS with clustered SEs, prefer `pyfixest`/`fixest` — native cluster support)
│ ├─ Fixed effects, IV with FE, or DiD → Load `pyfixest` skill (Python) or `fixest` skill (R)
│ ├─ Random effects, between, first difference, Fama-MacBeth → Load `linearmodels` skill (Python) or `plm` skill (R)
│ ├─ IV without FE (LIML, GMM) → Load `linearmodels` skill (Python) or `plm` skill (R)
│ ├─ System estimation (SUR, 3SLS) → Load `linearmodels` skill (Python) or `plm` skill (R)
│ ├─ Time series modeling (ARIMA/SARIMAX, VAR, forecasting, stationarity
│ │ tests, exponential smoothing) → Load `statsmodels` skill (Python) or
│ │ `r-stats` skill (R, see its references/time-series.md)
│ │ (to *describe* trends or seasonality without formal modeling, read
│ │ ./references/descriptive-analysis.md "Trend Analysis" section instead)
│ └─ Spatial regression (spatial lag, spatial error, GWR) → Load `geopandas` skill (Python) or `sf-terra` skill (R)
│ (Python: PySAL/spreg via geopandas; R: spdep/spatialreg via sf-terra; also read geospatial refs)
├─ Supervised ML (prediction, classification, risk scoring)
│ └─ FIRST read ./references/supervised-ml.md (when to use ML, how to validate, interpret, report)
│ THEN load `scikit-learn` skill (Python) or `tidymodels` skill (R) (algorithms, syntax, evaluation)
│ ├─ Model interpretation (SHAP, feature importance)
│ │ → Read supervised-ml.md "Interpreting ML Models" + scikit-learn/tidymodels interpretation refs
│ └─ Fairness assessment
│ → Read supervised-ml.md "Fairness" + scikit-learn/tidymodels fairness refs
├─ Unsupervised analysis (clustering, dimensionality reduction, pattern discovery)
│ └─ Stage 8.1 — FIRST read ./references/exploratory-unsupervised.md
│ THEN load `scikit-learn` skill (Python) or `tidymodels` skill (R)
│ ├─ Clustering → clustering.md, evaluation-unsupervised.md (scikit-learn refs; R: tidymodels unsupervised.md)
│ ├─ Dimensionality reduction → decomposition.md, manifold.md (scikit-learn refs; R: tidymodels unsupervised.md)
│ └─ Index construction via PCA → also read ./references/descriptive-analysis.md
├─ Causal / quasi-experimental analysis
│ └─ FIRST read ./references/causal-inference.md
│ THEN load appropriate library skill:
│ Python: pyfixest for DiD/IV/FE, linearmodels for panel RE/IV-GMM
│ R: fixest for DiD/IV/FE, plm for panel RE
│ For RD implementation (rdrobust) → also read ./references/causal-rd.md
│ For matching/IPW/AIPW implementation → also read ./references/causal-matching.md
│ For Heckman selection correction → also read ./references/causal-selection.md
│ For synthetic control implementation → also read ./references/causal-synth.md
│ For causal ML (DML, CATE, meta-learners, causal forests) → also read ./references/causal-ml.md
│ For mediation analysis (mechanisms, NDE/NIE) → also read ./references/causal-mediation.md
│ (reference files show Python implementations; in R, map to fixest/plm/r-stats
│ per the Language Routing table and the R library skills' own references)
├─ Complex survey data analysis (NHANES, ACS PUMS, CPS, ECLS-K, MEPS, etc.)
│ └─ FIRST read ./references/survey-analysis.md (methodology, pitfalls, weight selection)
│ THEN load `svy` skill (Python) or `survey-r` skill (R)
│ ├─ Survey-weighted descriptive statistics → svy/survey-r estimation refs
│ ├─ Survey-weighted regression (OLS, logistic, Poisson) → svy/survey-r regression refs
│ ├─ Survey design setup / replicate weights → svy/survey-r design-weights refs
│ └─ Advanced models not in svy (ordinal, survival, IV) → rpy2 + R survey package
│ (Python: see svy skill "rpy2 Bridge" section; R: use `survey-r` skill directly — rpy2 bridge not needed)
├─ Creating formatted tables (data summaries, regression output)
│ └─ Python: Load `great-tables` skill (grammar-of-tables display tables,
│ HTML/LaTeX export). No modelsummary equivalent — for regression tables
│ use library-specific output (e.g., pyfixest etable(), statsmodels summary())
│ R: Load `gt` skill (gt for data tables, modelsummary for regression
│ tables, kableExtra for simple Quarto tables)
├─ Communicating to non-technical audiences
│ └─ Load `science-communication` skill
├─ Geospatial / spatial analysis (any kind)
│ └─ FIRST read methodology reference files:
│ ├─ ./references/geospatial-analysis.md (spatial thinking, methods, interpretation)
│ └─ ./references/geospatial-operations.md (joins, weights, interpolation, operations)
│ THEN load `geopandas` skill (Python) or `sf-terra` skill (R)
├─ Network / graph analysis (relationships, centrality, community detection,
│ bipartite/two-mode data, paths/components, ego networks, network visualization)
│ └─ FIRST read ./references/network-analysis.md (when a network frame fits,
│ node/edge/directedness/weight conceptualization, centrality selection,
│ community detection + seed discipline, bipartite projection, disconnected-graph
│ and weights-as-distances guardrails, reproducibility requirements)
│ THEN load `igraph` skill (Python) or `igraph-r` skill (R)
│ (ERGM / statistical network models are not currently covered — see the
│ reference's "Out of Current Scope" note; escalate to orchestrator)
└─ Not currently covered by DAAF skills:
├─ Bayesian modeling (PyMC, bambi / brms) → escalate to orchestrator
├─ Survival / time-to-event analysis → escalate to orchestrator
└─ Deep learning (PyTorch, TensorFlow / torch for R) → escalate to orchestrator
The THEN-load steps apply to advisory and brainstorming turns as much as implementation. Recommending a method, reviewing a plan, or talking through an approach that names a tool needs the routed library skill loaded just as much as writing code does. The library skills encode environment-specific constraints (which estimators and export backends are actually installed and working here) and curated caveats that general knowledge lacks or gets wrong — for example, when a familiar tool is statistically inappropriate for the data at hand. Naming a tool in advice without loading its skill risks recommending an approach this environment cannot run, or one the skill's curated caveats explicitly warn against. The norm extends one hop further: once the routed library skill is loaded, its own reference-file routing carries the same advisory-inclusive expectation — answer from its routed reference files, not just its SKILL.md overview.
Visualization loading order matters: The reference files provide design principles (what chart to use, how to direct attention, how to handle color accessibly). The tool skills provide syntax (how to code it). Read the design guidance first so implementation choices are principled, not ad-hoc.
For Domain-Specific Analysis (e.g., CCD Education Data):
- Load relevant
*-data-source-*skill first to understand domain-specific data caveats - Then apply data-scientist methodology with that context
Prerequisite Knowledge: This skill assumes familiarity with:
- Python or R programming basics
- DataFrame concepts (rows, columns, filtering)
- Basic statistical concepts (mean, distribution, correlation)
Important: This skill provides the METHODOLOGY. The specialized skills provide TOOL KNOWLEDGE. Use both together — on advisory and brainstorming turns as much as when writing code. A methodology answer that names a tool without its skill loaded rests on general knowledge, which misses the environment constraints and curated caveats the tool skills encode.
Reference File Structure
| File | Purpose | When to Read |
|---|---|---|
eda-checklist.md | Detailed EDA procedures and validation checks | Starting analysis on new data |
data-documentation.md | Understanding and creating data documentation | Working with unfamiliar data |
transformation-validation.md | Validating data operations | Before/after any transformation |
code-documentation.md | Writing thorough comments and docs | Writing any analysis code |
research-questions.md | Framing questions, stakeholder communication | Scoping work, presenting findings |
visualization-design.md | Chart selection, visual encoding, emphasis, integrity | Before creating any visualization |
visualization-execution.md | Color palettes, accessibility, labeling, typography, export | When producing figures |
descriptive-analysis.md | Summary statistics, subgroups, distributions, decompositions, weighting, inequality, correlation, missing data | Stage 8 analysis when the research contribution is descriptive |
statistical-modeling.md | Model selection, assumption checking, robust inference, coefficient interpretation, robustness checks | Stage 8.1 analysis involving regression, modeling, or hypothesis testing. For formal time-series estimation (ARIMA/SARIMAX, VAR, forecasting), load the statsmodels skill directly |
causal-inference.md | Causal identification, DAGs, RCTs, IV, RD, DiD, synthetic control, matching | Stage 8.1 analysis requiring causal claims |
causal-rd.md | Regression discontinuity implementation: rdrobust API (sharp, fuzzy, kink), bandwidth selection, manipulation testing, covariate balance, visualization, diagnostics | Stage 8.1 analysis using regression discontinuity designs |
causal-matching.md | Matching (NN, caliper, Mahalanobis, exact, CEM), IPW, doubly robust/AIPW implementation with sklearn + statsmodels + scipy + polars; balance diagnostics; inference | Stage 8.1 analysis using matching, propensity scores, IPW, or AIPW methods |
causal-synth.md | Synthetic control implementation: manual scipy, pysyncon, synthdid, scpi-pkg, CausalPy; inference methods; SDID; gotchas | Stage 8.1 analysis using synthetic control or SDID methods |
causal-ml.md | Causal ML implementation: manual DML (partially linear + interactive/AIPW) with sklearn + statsmodels + pyfixest; S/T-learner (manual); EconML patterns (LinearDML, CausalForestDML, meta-learners, DR-learner); DoubleML patterns (PLR, IRM, sensitivity); causal forests (EconML + R grf); CATE diagnostics (overlap, GATES, BLP); gotchas | Stage 8.1 analysis using DML, CATE estimation, meta-learners, or causal forests |
causal-selection.md | Heckman selection model implementation: manual two-step (Probit + OLS + IMR), FIML via scipy, bootstrap inference, exclusion restriction diagnostics, IMR collinearity checks; no statsmodels.heckman module exists | Stage 8.1 analysis where the outcome is observed only for a non-random subset (sample selection bias) |
causal-mediation.md | Causal mediation analysis: statsmodels Mediation (Imai et al. 2010), manual bootstrap, NDE/NIE decomposition, moderated mediation, multiple mediators, sensitivity analysis (E-value), gotchas | Stage 8.1 analysis decomposing causal effects into direct and indirect pathways (mechanisms) |
survey-analysis.md | Complex survey methodology: design anatomy, weight selection, variance estimation, domain estimation, plausible values, survey-weighted regression, federal survey reference table, pitfalls checklist | Any task involving data from a complex probability survey (NHANES, ACS PUMS, CPS, ECLS-K, HSLS, MEPS, NAEP, etc.) |
geospatial-analysis.md | Spatial thinking, MAUP, CRS, methods decision guide, autocorrelation, regression | Any task involving geographic/spatial data |
geospatial-operations.md | Spatial joins, weights, LISA interpretation, interpolation, zonal statistics, geometry validity | Planning or executing spatial operations (joins, overlays, weights, interpolation, zonal statistics), or interpreting spatial statistics results (Moran's I, LISA) |
network-analysis.md | Network/graph methodology: when a network frame fits, node/edge/directedness/weight conceptualization, centrality selection by research question, community detection + seed discipline, bipartite/two-mode data and projection, disconnected-graph and weights-as-distances guardrails, reproducibility; ERGM out of scope | Any task involving relational/network data — centrality, community detection, paths/components, bipartite graphs, ego networks, or network visualization |
exploratory-unsupervised.md | Cluster analysis, dimension reduction (PCA), Gaussian mixture models, nonlinear embeddings (t-SNE, UMAP), cluster validation, classify-analyze problem | Stage 8 tasks involving unsupervised methods, typology construction, or pattern discovery |
supervised-ml.md | Supervised ML methodology: prediction vs. inference (Shmueli 2010), bias-variance tradeoff, cross-validation for structured data (grouped, temporal, spatial), model selection, classification and ML regression methodology, ensemble methods, interpretation caveats (feature importance is not causation), algorithmic fairness and equity (impossibility theorems), deep learning orientation, reporting standards | Stage 8 tasks involving classification, prediction, risk scoring, ML-based variable selection, or any task where the goal is predicting outcomes rather than estimating causal parameters |
Validation Tracking
For multi-step transformations, track validation state with a simple dict (Python) or named list (R):
Python:
validation_log = {}
# After each transformation step:
validation_log["Filter to high schools"] = {
"pre_rows": pre_rows,
"post_rows": result.shape[0],
"status": "PASSED" if result.shape[0] > 0 else "FAILED",
}
# Print summary at end:
for step, info in validation_log.items():
print(f" [{info['status']}] {step}: {info['pre_rows']:,} → {info['post_rows']:,}")
R:
validation_log <- list()
# After each transformation step:
validation_log[["Filter to high schools"]] <- list(
pre_rows = pre_rows,
post_rows = nrow(result),
status = if (nrow(result) > 0) "PASSED" else "FAILED"
)
# Print summary at end:
for (step in names(validation_log)) {
info <- validation_log[[step]]
cat(sprintf(" [%s] %s: %s -> %s\n", info$status, step,
format(info$pre_rows, big.mark = ","),
format(info$post_rows, big.mark = ",")))
}
This is inline code, not a separate module. Never create a validation.py / validation.R or import a validation class.
Quick Decision Trees
"I'm starting a new analysis"
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 235
- Forks
- 34
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
data-scientist-daaf-contribution-community- Source
- github.com/daaf-contribution-community/daaf