Package: xport
Read and write SAS Transport files (*.xpt).SAS uses a handful of archaic file formats: XPORT/XPT, CPORT, SAS7BDAT.
If someone publishes their data in one of those formats, this Python
package will help you convert the data into a more useful format.  If
someone, like the FDA, asks you for an XPT file, this package can write
it for you.What’s it for?XPORT is the binary file format used by a bunch ofUnited States
government agenciesfor publishing data sets. It made a lot of sense
if you were trying to read data files on your IBM mainframe back in
1988.The officialSAS specification for XPORTis relatively
straightforward. The hardest part is converting IBM-format floating
point to IEEE-format, which the specification explains in detail.There was anupdate to the XPT specificationfor SAS v8 and above.
This modulehas not yet been updatedto work with the new version.
However, if you’re using SAS v8+, you’re probably not using XPT
format. The changes to the format appear to be trivial changes to the
metadata, but this module’s current error-checking will raise aValueError. If you’d like an update for v8, please let me know bysubmitting an issue.InstallationThis project requires Python v3.7+.  Grab the latest stable version from
PyPI.$python-mpipinstall--upgradexportReading XPTThis module follows the common pattern of providingloadandloadsfunctions for reading data from a SAS file format.importxport.v56withopen('example.xpt','rb')asf:library=xport.v56.load(f)The XPT decoders,xport.loadandxport.loads, return axport.Library, which is a mapping (dict-like) ofxport.Dataset``s.The ``xport.Dataset`is a subclass ofpandas.DataFramewith SAS metadata attributes (name, label, etc.).
The columns of axport.Datasetarexport.Variabletypes, which
are subclasses ofpandas.Serieswith SAS metadata (name, label,
format, etc.).If you’re not familiar withPandas’s dataframes, it’s easy to think
of them as a dictionary of columns, mapping variable names to variable
data.The SAS Transport (XPORT) format only supports two kinds of data.  Each
value is either numeric or character, soxport.loaddecodes the
values as eitherstrorfloat.Note that since XPT files are in an unusual binary format, you should
open them using mode'rb'.You can also use thexportmodule as a command-line tool to convert
an XPT file to CSV (comma-separated values) file.  Thexportexecutable is a friendly alias forpython-mxport. Caution: if this command-line does not work with the lastest version, it should be working with version 2.0.2. To get this version, we can either download the files from thislinkor simply type the following command line your bash terminal:pip installxport==2.0.2.$xportexample.xpt>example.csvWriting XPTThexportpackage follows the common pattern of providingdumpanddumpsfunctions for writing data to a SAS file format.importxportimportxport.v56ds=xport.Dataset()withopen('example.xpt','wb')asf:xport.v56.dump(ds,f)Because thexport.Datasetis an extension ofpandas.DataFrame,
you can create datasets in a variety of ways, converting easily from a
dataframe to a dataset.importpandasaspdimportxportimportxport.v56df=pandas.DataFrame({'NUMBERS':[1,2],'TEXT':['a','b']})ds=xport.Dataset(df,name='MAX8CHRS',label='Up to 40!')withopen('example.xpt','wb')asf:xport.v56.dump(ds,f)SAS Transport v5 restricts variable names to 8 characters (with a
strange preference for uppercase) and labels to 40 characters.  If you
want the relative comfort of SAS Transport v8’s limit of 246 characters,
pleasemake an enhancement request.It’s likely that most people will be usingPandasdataframes for the
bulk of their analysis work, and will want to convert to XPT at the
very end of their process.importpandasaspdimportxportimportxport.v56df=pd.DataFrame({'alpha':[10,20,30],'beta':['x','y','z'],})...# Analysis work ...ds=xport.Dataset(df,name='DATA',label='Wonderful data')# SAS variable names are limited to 8 characters.  As with Pandas# dataframes, you must change the name on the dataset rather than# the column directly.ds=ds.rename(columns={k:k.upper()[:8]forkinds})# Other SAS metadata can be set on the columns themselves.fork,vinds.items():v.label=k.title()ifv.dtype=='object':v.format='$CHAR20.'else:v.format='10.2'# Libraries can have multiple datasets.library=xport.Library({'DATA':ds})withopen('example.xpt','wb')asf:xport.v56.dump(library,f)Feature requestsI’m happy to fix bugs, improve the interface, or make the module
faster.  Justsubmit an issueand I’ll take a look.  If you work for
a corporation or well-funded non-profit, please consider asponsorship.ThanksCurrent and past sponsors include:ContributingThis project is configured to be developed in a Conda environment.$gitclonegit@github.com:selik/xport.git$cdxport$makeinstall# Install into a Conda environment$condaactivatexport# Activate the Conda environment$makeinstall-html# Build the docs websiteAuthorsOriginal version byJack Cushman, 2012.Major revisions byMichael Selik, 2016 and 2020.Minor revisions byAlfred Chan, 2020.Minor revisions byDerek Croote, 2021.Change Logv0.1.0, 2012-05-02Initial release.v0.2.0, 2016-03-22Major revision.v0.2.0, 2016-03-23Add numpy and pandas converters.v1.0.0, 2016-10-21Revise API to the pattern of from/to <format>v2.0.0, 2016-10-21Reader yields regular tuples, not namedtuplesv3.0.0, 2020-04-20Revise API to the load/dump pattern.
Enable specifying dataset name, variable names, labels, and formats.v3.1.0, 2020-04-20Allowdumps(dataframe)instead of requiring aDataset.v3.2.2, 2020-09-03Fix a bug that incorrectly displays a - (dash) when it’s a null for numeric field.v3.3.0, 2021-12-25Enable reading Transport Version 8/9 files.  Merry Christmas!v3.4.0, 2021-12-25Add support for special missing values, like.A, that extendfloat.v3.5.0, 2021-12-31Enable writing Transport Version 8 files.  Happy New Year!v3.5.1, 2022-02-01Fix issues with writingDataset.labelandVariable.label.v3.6.0, 2022-02-02Add beta support for changing the text encoding for data and metadata.v3.6.1, 2022-02-15Fix issue with v8 format when the dataset has no long labels.