Skill: Data Analyst

The Data Analyst skill turns Claude into a data scientist who writes clean, reproducible Python analysis code. Instead of one-off scripts that nobody can re-run, you get a structured workflow: load, inspect, clean, analyze, visualize — each step in its own code block with the reasoning written out alongside it.

What This Skill Does

When triggered, Claude follows a five-step workflow and outputs the Python code for each step:

  1. Load — reads the data with pandas, handling different file formats (CSV, JSON, Excel, Parquet).
  2. Inspect — runs head(), info(), describe() to understand shape, types, and distributions before touching anything.
  3. Clean — handles missing values, fixes column types, removes duplicates, and documents every transformation.
  4. Analyze — runs the actual analysis: groupby, pivot tables, correlations, statistical tests.
  5. Visualize — produces charts with matplotlib or seaborn, labeled and ready to drop into a report.

Two hard rules keep the output useful: Claude always outputs the Python code block (not just a description), and it explains the statistical significance of findings — not just "the mean is 42" but whether the difference actually means something.

How to Install

  1. Create the skills directory:
    mkdir -p .claude/skills/data-analyst
    
  2. Save the template below as .claude/skills/data-analyst/SKILL.md.
  3. Trigger it with a prompt like: "Analyze sales.csv using the data-analyst skill. I want to know which regions grew fastest last quarter."

SKILL.md Template

# Data Analyst Skill

## Triggers
- "Analyze data"
- "Visualize this"
- "Clean this CSV"

## Workflow
1.  **Load:** Read data using pandas.
2.  **Inspect:** Check `head()`, `info()`, `describe()`.
3.  **Clean:** Handle missing values, fix types.
4.  **Analyze:** GroupBy, Pivot, Correlation.
5.  **Visualize:** Use matplotlib/seaborn.

## Rules
- Always output the python code block.
- Explain the statistical significance of findings.

Real-World Usage Example

Prompt:

Analyze this CSV using the data-analyst skill. The file is orders.csv with columns: order_id, region, date, amount. Which region had the highest average order value last quarter, and is the difference statistically significant?

Expected output:

1. Load

import pandas as pd

df = pd.read_csv('orders.csv', parse_dates=['date'])

2. Inspect

print(df.head())
print(df.info())
print(df.describe())

Check for nulls in amount and confirm date parsed correctly.

3. Clean

df = df.dropna(subset=['amount', 'region', 'date'])
df['amount'] = pd.to_numeric(df['amount'], errors='coerce')
df = df.dropna(subset=['amount'])

4. Analyze

last_quarter = df[df['date'] >= '2024-10-01']
aov = last_quarter.groupby('region')['amount'].mean().sort_values(ascending=False)
print(aov)

from scipy import stats
top_region = aov.index[0]
second_region = aov.index[1]
t, p = stats.ttest_ind(
    last_quarter[last_quarter['region'] == top_region]['amount'],
    last_quarter[last_quarter['region'] == second_region]['amount'],
    equal_var=False
)
print(f"p-value: {p:.4f}")

5. Visualize

import matplotlib.pyplot as plt
import seaborn as sns

sns.barplot(data=last_quarter, x='region', y='amount', estimator='mean')
plt.title('Average Order Value by Region (Last Quarter)')
plt.ylabel('Average Amount ($)')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('aov_by_region.png', dpi=150)

Findings: The top region's average order value is higher than the second region's. The p-value tells you whether that gap is likely real or just sampling noise. A p-value below 0.05 means the difference is statistically significant; above 0.05 means you can't rule out random variation with this sample size.

Customization Tips

  • Pin your stack. If you use polars instead of pandas, or plotly instead of matplotlib, swap the library names in the workflow section. Claude will use what you specify.
  • Add a "no silent failures" rule. Append "Raise on unexpected null counts. Print a warning if more than 5% of rows are dropped during cleaning." This surfaces data quality issues instead of hiding them.
  • Require a data dictionary. Add "Before cleaning, output a table of columns, types, and null counts." You get an audit trail of what the raw data looked like.
  • Set a chart style. Add "Use sns.set_theme(style='whitegrid') before plotting." Your charts will look consistent across analyses.

Combining With Other Skills

  • technical-writer — After the analysis is done, hand the findings to technical-writer to produce a structured report. The analyst provides the numbers; the writer provides the narrative.
  • code-reviewer — Run code-reviewer on the generated analysis script to catch issues like chained indexing (df[df['x']>0]['y'] = ...) that pandas silently ignores.
  • security-auditor — If the dataset contains PII, run security-auditor on the script to check for data leakage in logs or saved charts.

Common Mistakes to Avoid

  • Not specifying the file format. "Analyze this data" without mentioning CSV vs. JSON vs. Excel leads to wrong loader code. Always name the file and format.
  • Skipping the inspect step. If Claude jumps straight to analysis without checking types and nulls, the results can be wrong in ways that don't error — strings where numbers should be, silent NaN propagation.
  • Ignoring sample size. A mean difference with 12 data points is not the same as one with 12,000. The skill asks for statistical significance for this reason — read the p-value, don't just look at the bar chart.
  • Not saving charts to files. plt.show() doesn't work in headless environments. The template uses plt.savefig() — keep it that way unless you're running in a notebook.