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.1 - Bug Fix Release
Critical bug fix for XPT column name handling.
New in v0.4.1:
- 🐛 CRITICAL FIX: Column name length limit corrected from 8 to 32 characters
- ✅ XPT format properly supports 32-character column names (was incorrectly limited to 8)
- ✅ Fixed "duplicate column name" errors when using CREATE TABLE with long names
- ✅ No more manual column renaming needed for most use cases
Previous release (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
Choose storage format (sas7bdat is default, xpt for legacy compatibility):
saslite --workdir ./work --format sas7bdat path/to/program.sas
saslite --workdir ./work --format xpt 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
# Default: uses sas7bdat format for better compatibility
sas = SasInterpreter()
# Or explicitly specify format
sas = SasInterpreter(sas_format='sas7bdat') # Recommended (default)
sas = SasInterpreter(sas_format='xpt') # Legacy XPT format
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)
Storage Formats
SASLite supports two storage format options:
- sas7bdat (default): Uses .sas7bdat file extension for better tool compatibility
- xpt: Uses .xpt file extension (SAS Transport format)
Important Note: Due to Python library limitations, both formats currently use the XPT (Transport) file format internally. This means:
- Column names are limited to 32 characters (XPT format constraint)
- Files use the XPT binary format regardless of extension
- Files are fully compatible with SAS software and other SAS readers
- The XPT format is actually quite robust: stable, well-documented, and has excellent library support
Version 0.4.1 Note: The column name limit was corrected from an incorrect 8-character limit to the proper 32-character limit specified by the XPT format.
The format can be configured via:
- Python API:
SasInterpreter(sas_format='sas7bdat')orSasInterpreter(sas_format='xpt') - CLI:
saslite --format sas7bdatorsaslite --format xpt - Direct backend:
SasBackend('./work', format='sas7bdat')
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.andLAST.,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() OVERwithPARTITION BYandORDER 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 Step02_proc_sql.sas- SQL with window functions03_macro_programming.sas- Macros and %SYSFUNC04_statistical_analysis.sas- MEANS, FREQ, CORR, TTEST05_linear_regression.sas- PROC REG06_logistic_regression.sas- PROC LOGISTIC07_advanced_data_manipulation.sas- Functions and arrays08_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-score4shorthand - 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file saslite-0.4.1.tar.gz.
File metadata
- Download URL: saslite-0.4.1.tar.gz
- Upload date:
- Size: 166.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f351195c31d72cc0f8a4c0de1394c8c0a656984204dc8d8083f87718677550b
|
|
| MD5 |
23b7b18b38b18a6d2f74bb9b60aa605c
|
|
| BLAKE2b-256 |
d7256bc5e8f2ad6de580f53f6ad05d5e78d92d6f0ae27acc5ffe41390bb69327
|
File details
Details for the file saslite-0.4.1-py3-none-any.whl.
File metadata
- Download URL: saslite-0.4.1-py3-none-any.whl
- Upload date:
- Size: 162.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7070d1d2619d8f0a28f20ff854f1afb8df7ffc1c1a560785cb7f631757582162
|
|
| MD5 |
eb64a3908ad25671c3b781061ac63ec5
|
|
| BLAKE2b-256 |
6466205522d16c510cb86eb9091f58c37f955fc7edcd1179a030cbc349898bdc
|