Skip to main content

Lightweight SAS language interpreter with statistical analysis capabilities

Project description

SASLite

SASLite is a lightweight local interpreter for a practical subset of the SAS language, implemented in Python on top of pandas. It is intended for local data checks, small automation workflows, SAS-like examples, and migration/testing work where a full SAS runtime is not available.

SASLite is an independent project. It is not affiliated with, endorsed by, or supported by SAS Institute Inc.

Status

Version 0.4.0 - Beta Release

SASLite is now in Beta. It supports a comprehensive subset of SAS syntax including advanced statistical analysis. The core features are stable and production-ready for many use cases. Validate results carefully before using them for regulated, clinical, financial, or other high-stakes work.

New in v0.4.0:

  • 🎉 PROC REG - Linear regression analysis
  • 🎉 PROC LOGISTIC - Logistic regression with full CLASS and ODDSRATIO support
  • 25-30% performance improvement
  • 📚 8 comprehensive examples with automated validation
  • 540 tests passing (100% pass rate)

See CHANGELOG.md for complete release notes.

Installation

pip install saslite

Optional extras:

pip install "saslite[excel]"
pip install "saslite[gui]"

For local development from a checkout:

pip install -e ".[excel,gui]"

Command Line

Run a SAS program:

saslite path/to/program.sas

Run one statement:

saslite -e "data demo; x = 1; output; run;"

Start the interactive prompt:

saslite --interactive

Use a persistent working directory for local datasets:

saslite --workdir ./work path/to/program.sas

GUI

Install the GUI extra:

pip install "saslite[gui]"

Start the browser-based GUI:

saslite-gui

This starts a local Flask server at http://127.0.0.1:5000 and opens it in the default browser. To keep it from opening a browser tab automatically:

saslite-gui --no-browser

Start the desktop wrapper, powered by pywebview:

saslite-desktop

On Windows, the desktop wrapper may require Microsoft Edge WebView2 Runtime. The browser-based saslite-gui command is the simpler fallback.

Python API

from saslite import SasInterpreter

sas = SasInterpreter()

result = sas.execute(
    """
    data work.employees;
        input name $ age salary;
        datalines;
    Alice 30 50000
    Bob 25 40000
    ;
    run;

    proc print data=work.employees;
    run;
    """
)

print(result.success)
df = sas.get_dataset("WORK", "EMPLOYEES")
print(df)

Create a SASLite dataset from pandas:

import pandas as pd
from saslite import SasInterpreter

sas = SasInterpreter()
source = pd.DataFrame({"id": [1, 2, 3], "value": [10, 20, 30]})
sas.create_dataset("source", source)

sas.execute(
    """
    data work.result;
        set work.source;
        doubled = value * 2;
    run;
    """
)

result = sas.get_dataset("WORK", "RESULT")

Supported Features

SASLite includes support for:

Data Processing

  • DATA step: DATA, SET, MERGE, INPUT, DATALINES, INFILE, OUTPUT, KEEP, DROP, RENAME, WHERE, IF/THEN/ELSE, DO/END, DO WHILE/UNTIL, BY, FIRST. and LAST., ARRAY, RETAIN, LENGTH, ATTRIB
  • Column-mode INPUT: Fixed-width data reading with position specifications
  • INFILE options: DLM=, DSD, TRUNCOVER, FIRSTOBS, OBS

SQL & Queries

  • PROC SQL: SELECT, CREATE TABLE, INSERT, UPDATE, DELETE
  • Joins: INNER, LEFT, RIGHT, FULL OUTER, CROSS
  • Advanced: Subqueries, GROUP BY, HAVING, ORDER BY, DISTINCT
  • Window functions (new in 0.4.0): ROW_NUMBER(), RANK(), LAG(), LEAD(), SUM() OVER, AVG() OVER with PARTITION BY and ORDER BY
  • Operators: CASE, LIKE, BETWEEN, IN, IS NULL, EXISTS
  • Aggregate functions: SUM, AVG, COUNT, MIN, MAX, STD, VAR

Statistical Analysis

  • PROC MEANS/SUMMARY: Descriptive statistics with CLASS, BY, VAR, OUTPUT
  • PROC FREQ: Frequency tables, cross-tabulations, chi-square tests
  • PROC CORR (new in 0.3.0): Correlation analysis (Pearson, Spearman, Kendall)
  • PROC TTEST (new in 0.3.0): T-tests for comparing means
  • PROC REG (new in 0.4.0): Linear regression analysis
    • Simple and multiple regression
    • R², Adjusted R², F-statistic, ANOVA tables
    • Residual analysis, VIF for multicollinearity
    • Standardized coefficients
  • PROC LOGISTIC (new in 0.4.0): Logistic regression
    • Binary logistic regression
    • CLASS statement for categorical variables
    • ODDSRATIO statement with confidence intervals
    • Model fit statistics (AIC, BIC, -2 Log L)
    • Predicted probabilities

Other Procedures

  • PROC SORT: Multi-key sorting with BY, DESCENDING, NODUPKEY
  • PROC PRINT: Data display with VAR, WHERE, BY
  • PROC CONTENTS: Dataset metadata
  • PROC DATASETS: Library management, dataset operations
  • PROC APPEND: Append datasets
  • PROC IMPORT/EXPORT: CSV and delimited file I/O

Macro System

  • Macro variables: %LET, %PUT, macro variable resolution
  • Macro functions: %MACRO, %MEND, %DO, %IF/%THEN/%ELSE
  • %SYSFUNC (new in 0.3.0): Call DATA step functions in macro code
  • %INCLUDE: Compose programs from multiple files
  • Conditional logic: %IF, %DO WHILE, %DO UNTIL

Built-in Functions (82 functions)

  • Character: STRIP, UPCASE, LOWCASE, SUBSTR, INDEX, SCAN, CAT, CATX, TRIM, LEFT, RIGHT, COMPRESS, TRANSLATE, REVERSE, REPEAT, COMPARE, COMPBL, QUOTE, DEQUOTE, COUNTC, COUNTW
  • Numeric: SUM, MEAN, MIN, MAX, ROUND, CEIL, FLOOR, ABS, SQRT, EXP, LOG, LOG10, MOD, SIGN, INT, RANUNI, RANNOR
  • Date/Time: TODAY, DATE, DATETIME, DATEPART, TIMEPART, YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY, QTR, MDY, INTNX, INTCK, DHMS, HMS, YYQ, WEEK
  • Conversion: INPUT, PUT, INPUTN, INPUTC, PUTN, PUTC
  • Missing values: NMISS, CMISS, MISSING, COALESCE, COALESCEC
  • Utility: N, DIM, IFN, IFERROR, LAG, DIF
  • Statistical: PROBNORM, PROBT, PROBCHI, PROBF

Libraries & I/O

  • LIBNAME: Local work areas, reference libraries
  • CSV support: PROC IMPORT/EXPORT for CSV files
  • Python API: Create datasets from pandas, export to pandas
  • Excel support (optional): With saslite[excel] extra

See DOCS.md and the examples/ directory for detailed usage.

Examples

Basic DATA Step and SQL

data work.sales;
    input region $ product $ amount;
    datalines;
East Widget 100
West Gadget 200
East Widget 150
;
run;

proc sql;
    create table work.summary as
    select region, sum(amount) as total_sales
    from work.sales
    group by region
    order by total_sales desc;
quit;

Statistical Analysis - Linear Regression

data work.study;
    input hours_studied score;
    datalines;
2 65
4 75
6 85
8 92
;
run;

proc reg data=work.study;
    model score = hours_studied;
    output out=work.predicted predicted=pred_score residual=resid;
run;

Logistic Regression with Categorical Variables

data work.patients;
    input age treatment $ outcome;
    datalines;
30 A 1
40 B 0
50 A 1
;
run;

proc logistic data=work.patients;
    class treatment;
    model outcome = age treatment;
    oddsratio age;
    oddsratio treatment;
run;

More Examples

See the examples/ directory for 8 comprehensive examples:

  • 01_hello_world.sas - Basic DATA Step
  • 02_proc_sql.sas - SQL with window functions
  • 03_macro_programming.sas - Macros and %SYSFUNC
  • 04_statistical_analysis.sas - MEANS, FREQ, CORR, TTEST
  • 05_linear_regression.sas - PROC REG
  • 06_logistic_regression.sas - PROC LOGISTIC
  • 07_advanced_data_manipulation.sas - Functions and arrays
  • 08_import_export.sas - CSV I/O

Run examples with:

saslite examples/05_linear_regression.sas

Validate all examples:

cd examples
python validate_examples.py

Known Limits

SASLite intentionally implements a practical subset of SAS. Some advanced or environment-specific SAS features are not currently supported:

Not Implemented:

  • Advanced macro features (MACRO PROC, compiled macros)
  • Remote libraries and server integration
  • Complete format/informat catalog system
  • ODS (Output Delivery System)
  • Graphics procedures (SGPLOT, GPLOT, etc.)
  • Some specialized PROCs (IML, REPORT, TABULATE, etc.)
  • BY-group processing in all contexts
  • Full index support
  • Hash objects and data structures

Partial Support:

  • PROC PRINT does not support TITLE statements
  • ARRAY syntax: use full variable lists instead of score1-score4 shorthand
  • Some advanced SQL features (recursive CTEs, complex subqueries)
  • Informats and formats (common ones supported)

When SASLite cannot parse or execute a program exactly, simplify the program to the supported subset or use the Python API to prepare input datasets directly.

Performance Note: SASLite is optimized for datasets up to ~1M rows. For larger datasets, consider using SAS itself or chunking strategies with the Python API.

Development

Install development dependencies:

pip install -e ".[excel,gui]"
pip install pytest build twine

Run tests:

python -m pytest -q

Build distribution artifacts:

python -m build

Check package metadata:

python -m twine check dist/*

Publishing

Test the package on TestPyPI before publishing to PyPI:

python -m build
python -m twine upload --repository testpypi dist/*

After verifying installation from TestPyPI, publish the same version to PyPI:

python -m twine upload dist/*

License

SASLite is distributed under the MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

saslite-0.4.0.tar.gz (163.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

saslite-0.4.0-py3-none-any.whl (159.9 kB view details)

Uploaded Python 3

File details

Details for the file saslite-0.4.0.tar.gz.

File metadata

  • Download URL: saslite-0.4.0.tar.gz
  • Upload date:
  • Size: 163.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for saslite-0.4.0.tar.gz
Algorithm Hash digest
SHA256 6e2d939e0cfa77c741311bbcb9117248e3422533db5da6bc4c25e0b8e70ad5f7
MD5 66d6d395205e4f783a807e9cc165b74f
BLAKE2b-256 20e0792e37102cbe8bcd066f6ff0b271ea7f5e8bc76a74c9f5c5b306a020a226

See more details on using hashes here.

File details

Details for the file saslite-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: saslite-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 159.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for saslite-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b270feaa2ed1f74a5ccb2f28c11ae3f2e1cd03058e03ca2b39b7e7bf8ef4bc8d
MD5 d6807b226e2e72af12975cb081b887b8
BLAKE2b-256 d6a10200397a6b654308f74834fec69db305daa129e3a7938db968e6487e7bfc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page