agentsclimarketplace

Data auditor

Skill tathadn/data-quality-skills-pipeline/skills/data-auditor

Automated data quality auditing pipeline using Claude Skills — generates multi-page PDF reports with charts and Excel workbooks from any CSV dataset.

Install
npx -y skills add tathadn/data-quality-skills-pipeline --skill data-auditor

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Audits CSV and Excel files for data quality issues and generates a professional PDF report with charts and figures, plus a detailed Excel workbook. Includes bar charts, pie charts, heatmaps, histograms, and trend analysis. Use this skill whenever the user uploads a dataset and asks for a quality check, data audit, data cleaning assessment, data profiling, or wants to know what's wrong with their data — even if they don't use the word 'audit'. Also trigger when users ask for a 'data health check', 'data quality report', or 'what should I clean in this data'.

SKILL.md

17.0 KB, ~4.5k tokens by cl100k_base, as published. Nobody here has run it

Data Auditor Skill

Purpose

Analyze any uploaded CSV or Excel dataset and produce:

  1. A professional PDF report with charts, figures, and written analysis
  2. A detailed Excel workbook with raw audit findings for further exploration

Both outputs are generated every time. The PDF is the primary deliverable for stakeholders; the Excel is the detailed backup for analysts.

Dependencies

Use these Python libraries (install if needed):

  • pandas — data loading and analysis
  • matplotlib — chart generation
  • seaborn — statistical visualizations and heatmaps
  • numpy — numerical computations
  • reportlab — PDF generation with embedded figures
  • openpyxl — Excel workbook generation

Import setup at the top of every script:

import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')  # Non-interactive backend — REQUIRED
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.backends.backend_pdf import PdfPages
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib.colors import HexColor
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, PageBreak,
    Table, TableStyle, Image as RLImage
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.chart import BarChart, PieChart, Reference
from datetime import datetime
import os
import tempfile

Color Palette

Use this consistent palette across ALL charts and the PDF:

COLORS = {
    'primary': '#1a56db',
    'accent': '#10b981',
    'warning': '#f59e0b',
    'danger': '#ef4444',
    'purple': '#8b5cf6',
    'gray_dark': '#374151',
    'gray_medium': '#6b7285',
    'gray_light': '#f3f4f6',
    'white': '#ffffff',
}

SEVERITY_COLORS = {
    'High': '#ef4444',
    'Medium': '#f59e0b',
    'Low': '#10b981',
}

# For matplotlib charts
CHART_PALETTE = ['#1a56db', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#06b6d4', '#84cc16']

Set matplotlib defaults:

plt.rcParams.update({
    'figure.facecolor': 'white',
    'axes.facecolor': 'white',
    'axes.edgecolor': '#e5e7eb',
    'axes.grid': True,
    'grid.alpha': 0.3,
    'grid.color': '#e5e7eb',
    'font.family': 'sans-serif',
    'font.size': 10,
    'axes.titlesize': 13,
    'axes.titleweight': 'bold',
    'axes.labelsize': 10,
    'figure.dpi': 150,
})

When to Use

Activate this skill when the user:

  • Uploads a CSV, TSV, or Excel file and asks about its quality
  • Requests a "data audit", "data check", "data profile", or "quality assessment"
  • Asks "what's wrong with this data?" or "is this data clean?"
  • Wants to know if a dataset is ready for analysis
  • Asks for a "data health check" or "data quality report"

Audit Procedure

Step 1: Load and Inspect

  • Load the uploaded file using pandas
  • Record: total rows, total columns, column names, inferred dtypes
  • Separate columns into categories: numeric, categorical, datetime, boolean
  • Display a brief preview (first 5 rows) for context

Step 2: Run Quality Checks

Perform ALL of the following checks on every applicable column:

Check 1: Missing Values

  • Count null, NaN, empty string, and whitespace-only values per column
  • Calculate missing percentage: (missing_count / total_rows) * 100
  • Severity: High if > 20%, Medium if 5-20%, Low if < 5%

Check 2: Duplicate Rows

  • Count exact duplicate rows across all columns
  • Count near-duplicates: rows that match on all columns except one
  • Severity: High if > 5% duplicates, Medium if 1-5%, Low if < 1%

Check 3: Data Type Validation

  • For each column, check if values match the expected type
  • Flag columns where > 10% of non-null values don't match the dominant type
  • Common issues: numbers stored as strings, dates stored as strings, mixed numeric/text
  • Severity: High if > 20%, Medium if 10-20%, Low if < 10%

Check 4: Outlier Detection (Numeric Columns Only)

  • Calculate IQR for each numeric column
  • Flag values below Q1 - 1.5IQR or above Q3 + 1.5IQR
  • Report count and percentage of outliers per column
  • Severity: High if > 10%, Medium if 3-10%, Low if < 3%
  • Skip columns with fewer than 10 non-null numeric values

Check 5: Date Format Consistency

  • Identify columns that contain date-like values
  • Check for mixed formats (e.g., MM/DD/YYYY vs DD-MM-YYYY vs YYYY-MM-DD)
  • Severity: High if > 2 formats, Medium if 2 formats, Low if consistent

Check 6: Text Casing Inconsistencies

  • For text columns, categorize values: ALL CAPS, all lower, Title Case, mixed
  • Flag columns where no single pattern covers > 80% of values
  • Severity: Medium if inconsistent, Low otherwise

Check 7: Whitespace Issues

  • Check for leading/trailing spaces in string values
  • Check for double spaces within values
  • Severity: Medium if > 10% affected, Low if < 10%

Check 8: Column Name Quality

  • Check for: spaces, special characters, inconsistent casing
  • Check for unnamed columns (e.g., "Unnamed: 0")
  • Severity: Low for naming issues, Medium if unnamed columns exist

Step 3: Calculate Health Score

Compute an overall score out of 100:

CategoryWeightScoring
Completeness30%100 - (avg missing % across all columns)
Uniqueness15%100 - (duplicate row %)
Type Consistency20%100 - (avg type mismatch % across columns)
Outlier Reasonability15%100 - (avg outlier % across numeric cols)
Format Consistency10%100 if all dates consistent, else penalize
Text Quality10%100 - (avg whitespace/casing issue %)

Interpretation:

  • 90-100: Excellent — minimal cleaning needed
  • 70-89: Good — some issues to address
  • 50-69: Fair — significant cleaning required
  • Below 50: Poor — major quality concerns

Step 4: Generate Charts

Save all charts as temporary PNG files for embedding in the PDF. Use plt.savefig() with bbox_inches='tight' and dpi=150.

Figure 1: Health Score Gauge

Create a donut/ring chart showing the overall health score:

fig, ax = plt.subplots(figsize=(4, 4))
score = health_score  # 0-100
colors_gauge = [COLORS['primary'] if score >= 70 else COLORS['warning'] if score >= 50 else COLORS['danger'], '#e5e7eb']
ax.pie([score, 100 - score], colors=colors_gauge, startangle=90, counterclock=False,
       wedgeprops={'width': 0.3, 'edgecolor': 'white', 'linewidth': 2})
ax.text(0, 0, f'{score}', fontsize=36, fontweight='bold', ha='center', va='center', color=COLORS['gray_dark'])
ax.text(0, -0.15, 'out of 100', fontsize=10, ha='center', va='center', color=COLORS['gray_medium'])
ax.set_title('Data Health Score', fontsize=14, fontweight='bold', pad=20)
plt.savefig(gauge_path, bbox_inches='tight', dpi=150)
plt.close()

Figure 2: Missing Values Bar Chart

Horizontal bar chart showing missing percentage per column:

fig, ax = plt.subplots(figsize=(8, max(4, len(columns_with_missing) * 0.4)))
# Sort by missing percentage descending
# Color bars by severity: red > 20%, orange 5-20%, green < 5%
# Add percentage labels at the end of each bar
# Add a vertical dashed line at 20% and 5% thresholds
ax.set_xlabel('Missing Values (%)')
ax.set_title('Missing Values by Column', fontsize=14, fontweight='bold')
plt.savefig(missing_path, bbox_inches='tight', dpi=150)
plt.close()

Only include columns that have at least some missing values. If no columns have missing values, skip this chart and note "No missing values detected" in the report.

Figure 3: Health Score Breakdown Pie Chart

Pie chart showing the weighted contribution of each quality category:

fig, ax = plt.subplots(figsize=(6, 6))
categories = ['Completeness', 'Uniqueness', 'Type Consistency', 'Outlier Reasonability', 'Format Consistency', 'Text Quality']
weights = [30, 15, 20, 15, 10, 10]
scores_per_category = [...]  # Each category's score * weight / 100
colors_pie = CHART_PALETTE[:6]
explode = [0.03] * 6
wedges, texts, autotexts = ax.pie(scores_per_category, labels=categories, colors=colors_pie,
    autopct='%1.0f%%', startangle=90, explode=explode,
    textprops={'fontsize': 9})
ax.set_title('Health Score Breakdown by Category', fontsize=14, fontweight='bold')
plt.savefig(pie_path, bbox_inches='tight', dpi=150)
plt.close()

Figure 4: Issue Severity Heatmap

A grid heatmap with columns on x-axis, check types on y-axis, cells colored by severity:

fig, ax = plt.subplots(figsize=(max(8, len(columns) * 0.6), 5))
# Create a matrix: rows = check types, columns = dataset columns
# Values: 0 = no issue, 1 = Low, 2 = Medium, 3 = High
# Use seaborn heatmap with custom colormap
cmap = sns.color_palette([COLORS['white'], COLORS['accent'], COLORS['warning'], COLORS['danger']])
# OR use ListedColormap
from matplotlib.colors import ListedColormap
severity_cmap = ListedColormap(['#f3f4f6', '#d1fae5', '#fef3c7', '#fee2e2'])
sns.heatmap(severity_matrix, ax=ax, cmap=severity_cmap, vmin=0, vmax=3,
    xticklabels=column_names, yticklabels=check_names,
    linewidths=1, linecolor='white', cbar=False,
    annot=severity_labels, fmt='s')  # severity_labels = matrix of "H"/"M"/"L"/""
ax.set_title('Issue Severity Heatmap', fontsize=14, fontweight='bold')
plt.xticks(rotation=45, ha='right', fontsize=8)
plt.savefig(heatmap_path, bbox_inches='tight', dpi=150)
plt.close()

If the dataset has more than 20 columns, only show the 20 columns with the most issues.

Figure 5: Distribution Histograms (Numeric Columns)

For each numeric column (up to 6), create a subplot histogram:

numeric_cols = df.select_dtypes(include=[np.number]).columns[:6]
n_cols = len(numeric_cols)
if n_cols > 0:
    fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(12, 7))
    axes = axes.flatten()
    for i, col in enumerate(numeric_cols):
        ax = axes[i]
        data = df[col].dropna()
        ax.hist(data, bins=30, color=CHART_PALETTE[i % len(CHART_PALETTE)], 
                edgecolor='white', alpha=0.85)
        # Add vertical lines for Q1, median, Q3
        q1, median, q3 = data.quantile([0.25, 0.5, 0.75])
        ax.axvline(median, color=COLORS['danger'], linestyle='--', linewidth=1.5, label=f'Median: {median:.1f}')
        # Mark IQR outlier boundaries
        iqr = q3 - q1
        lower = q1 - 1.5 * iqr
        upper = q3 + 1.5 * iqr
        ax.axvline(lower, color=COLORS['warning'], linestyle=':', linewidth=1, alpha=0.7)
        ax.axvline(upper, color=COLORS['warning'], linestyle=':', linewidth=1, alpha=0.7)
        ax.set_title(col, fontsize=11, fontweight='bold')
        ax.legend(fontsize=7)
    # Hide unused subplots
    for j in range(n_cols, len(axes)):
        axes[j].set_visible(False)
    fig.suptitle('Value Distributions (Numeric Columns)', fontsize=14, fontweight='bold', y=1.02)
    plt.tight_layout()
    plt.savefig(hist_path, bbox_inches='tight', dpi=150)
    plt.close()

Skip this figure entirely if the dataset has no numeric columns.

Figure 6: Trend Lines (Only If Date Column Exists)

If a date/datetime column is detected:

date_col = detected_date_column
numeric_cols_for_trend = df.select_dtypes(include=[np.number]).columns[:3]
if date_col and len(numeric_cols_for_trend) > 0:
    fig, axes = plt.subplots(nrows=len(numeric_cols_for_trend), ncols=1, 
                              figsize=(10, 3.5 * len(numeric_cols_for_trend)), sharex=True)
    if len(numeric_cols_for_trend) == 1:
        axes = [axes]
    for i, col in enumerate(numeric_cols_for_trend):
        ax = axes[i]
        # Sort by date, resample if needed (daily/weekly/monthly based on date range)
        sorted_df = df.sort_values(date_col)
        ax.plot(sorted_df[date_col], sorted_df[col], color=CHART_PALETTE[i], alpha=0.4, linewidth=0.8)
        # Add rolling average
        window = max(7, len(sorted_df) // 20)
        rolling = sorted_df[col].rolling(window=window, center=True).mean()
        ax.plot(sorted_df[date_col], rolling, color=CHART_PALETTE[i], linewidth=2, label=f'{window}-period avg')
        ax.set_ylabel(col, fontsize=10)
        ax.legend(fontsize=8)
    axes[-1].set_xlabel('Date')
    fig.suptitle('Trends Over Time', fontsize=14, fontweight='bold', y=1.01)
    plt.tight_layout()
    plt.savefig(trend_path, bbox_inches='tight', dpi=150)
    plt.close()

Skip entirely if no date column is detected. Note "No time-series data detected" in the report.

Step 5: Generate PDF Report

Use reportlab to create a professional multi-page PDF. Structure:

Page 1: Cover Page

  • Title: "Data Quality Audit Report"
  • Subtitle: Dataset filename
  • Date generated
  • Health Score gauge chart (Figure 1) centered
  • Summary stats: total rows, columns, issues found

Page 2: Executive Summary

  • 3-4 paragraph written summary of findings
  • Health Score Breakdown pie chart (Figure 3)
  • Key stats table (critical issues, warnings, info items)

Page 3: Missing Values Analysis

  • Missing Values bar chart (Figure 2)
  • Table listing columns with highest missing rates
  • Written interpretation

Page 4: Issue Severity Overview

  • Severity Heatmap (Figure 4)
  • Written interpretation of hotspots

Page 5: Distribution Analysis

  • Histograms grid (Figure 5)
  • Written notes on skewness, outliers detected
  • Skip this page if no numeric columns

Page 6: Trend Analysis (only if date column exists)

  • Trend line charts (Figure 6)
  • Written notes on observed patterns
  • Skip this page if no date column

Page 7: Detailed Findings Table

  • Full table of all issues found, sorted by severity
  • Columns: Column Name, Check Type, Severity, Finding, Affected Rows, Percentage

Page 8: Recommendations

  • Prioritized list of recommended actions
  • Each recommendation includes: what to fix, why, expected impact on health score

PDF Formatting Rules:

  • Page size: US Letter (8.5 x 11 inches)
  • Margins: 0.75 inches
  • Title font: Helvetica-Bold, 24pt, color #1a56db
  • Heading font: Helvetica-Bold, 16pt, color #374151
  • Body font: Helvetica, 10pt, color #4b5563
  • Table headers: white text on #1a56db background
  • Table rows: alternating white / #f3f4f6
  • Page numbers: bottom center
  • Header: "Data Quality Audit Report" on every page after cover

Step 6: Generate Excel Workbook

In addition to the PDF, produce an Excel file with three sheets:

Sheet 1: "Summary"

Rows: Dataset Name, Total Rows, Total Columns, Health Score, Health Rating, Critical Issues, Warnings, Info Items, Columns With Missing Data, Duplicate Rows, Date Generated.

Sheet 2: "Details"

Columns: Column Name, Check Type, Severity, Finding, Affected Rows, Percentage, Example Values. Sort by Severity (High first), then Affected Rows (descending).

Sheet 3: "Recommendations"

Columns: Priority, Issue, Recommendation, Affected Columns, Estimated Impact.

Excel Formatting:

  • Bold headers with #1a56db background, white text
  • Alternating row colors
  • Column auto-width
  • Conditional formatting: red fill for High severity, orange for Medium, green for Low
  • Freeze top row, enable filters

Step 7: Deliver Both Files

  • Save PDF as: audit_report_[dataset_name]_[YYYY-MM-DD].pdf
  • Save Excel as: audit_data_[dataset_name]_[YYYY-MM-DD].xlsx
  • Present both files to the user
  • Provide a brief verbal summary: health score, top 3 issues, and #1 recommendation

Edge Cases

  • Empty file: Return an error message, generate no report
  • Single row: Run checks but note "limited statistical validity" on every chart
  • All values missing in a column: Flag as Critical, recommend dropping
  • No numeric columns: Skip histograms and outlier detection, note in report
  • No date columns: Skip trend analysis page entirely
  • Very large files (> 100k rows): Sample 10,000 rows, note sampling on cover page
  • Fewer than 3 columns: Reduce heatmap size, adjust layout
  • Non-CSV/XLSX files: Inform user this skill only supports CSV and Excel

What NOT To Do

  • Do NOT modify or clean the original dataset — audit only
  • Do NOT skip chart generation — every applicable figure must be included
  • Do NOT use plt.show() — always use plt.savefig() then plt.close()
  • Do NOT generate charts for empty data — skip with a note instead
  • Do NOT output only text — both PDF and Excel are always required
  • Do NOT forget matplotlib.use('Agg') — will fail without display server

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.