SAS Viya Studio version: V.03.05
My understanding is that in CAS, a persisted .sashdat format file should be usable directly as a format without needing to recreate the original SAS PROC FORMAT definitions.
I suspect that the issue on my end may be due to administrative restrictions or configuration settings imposed by our SAS administrator.
Assuming no such restrictions are in place, I’m seeking guidance on what the expected process or solution should be to enable the use of persisted .sashdat format files as formats in CAS as intended.
I have studied and broken down (or attempted to) these various resources.
SAS Help Center: SAS Cloud Analytic Services 3.5: User-Defined Formats
SAS Help Center: Migrate User-Defined Formats from SAS to CAS
SAS Help Center: User-Defined Format Basics
SAS Viya CAS Format library persistence
Importing User-defined Formats to CAS in the SAS Viya Platform
https://www.youtube.com/watch?v=uC-Z5moTX9k
I’ve outlined my inquiry in 9 steps to provide full context. While steps 1–4 are foundational, they help set the stage for the more substantive points that follow.
Step 5 demonstrates empirically that SAS formats can be used within CAS.
Steps 6–7 result in the creation of a persisted .sashdat format file.
Steps 8–9, after initiating a new CAS session, attempt to use that persisted .sashdat file as a format within CAS.
I realize the explanation may seem verbose, but I wanted to ensure the context is clear. I appreciate any guidance or suggestions from those familiar with this process.
Please see full code with all relevant annotations.
/* connect to CAS + set-up libref for caslib */
cas CASauto sessopts=(caslib='CASuser');
libname CASuser cas caslib=CASuser;
/* 1) list and delete SAS formats <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) list all Custom formats */
proc catalog catalog=work.formats ;
contents out=format_catalog;
quit;
proc print data=format_catalog noobs; run;
/* b) delete all Custom formats from work.formats catalog*/
proc datasets library=work nolist;
delete formats / memtype=catalog;
quit;
/* 2) list and delete CAS formats <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) list all formats in all CAS libraries */
cas casauto listformats MEMBERS;
/* b) list all formats in the CAS library CASFormats */
cas casauto listformats fmtlibname=CASFormats SCOPE=BOTH /*GLOBAL|SESSION|BOTH*/ MEMBERS;
/* c) drop all formats in the CAS library CASFormats */
cas casauto dropfmtlib fmtlibname=CASFormats fmtsearchremove;
/* >>> using CAS action */
proc cas;
sessionProp.dropFmtLib /
fmtLibName='CASFormats'
fmtSearchRemove = TRUE;
quit;
/* 3) list and delete CAS .sashdat files <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) check for .sashdat files in CASuser*/
proc cas;
table.fileinfo
caslib='CASuser';
quit;
/* b) delete all files from CASuser (assuming some are persisted .sashdat format files) */
proc cas;
table.fileinfo result=r
caslib='CASuser';
do i = 1 to dim(r.fileInfo);
File_Name = r.fileinfo[i].Name;
table.deleteSource
caslib='CASuser'
source=File_Name;
end;
quit;
/* 4) create simple SAS data set + simple SAS format + apply SAS format <><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) raw data */
data raw;
infile datalines;
input var1 var2;
datalines;
1 10
2 10
;
/* b) create SAS only format */
proc format; /* <<< lib=work.formats is implicit*/
value frmt
1 = 'abc';
run;
/* ########## re-run 1a) to validate format exists in SAS
Result: LIBNAME: Work MEMNAME: FORMATS NAME: FRMT */
/* c) apply SAS only format to SAS Data Set */
data raw_frmt;
set raw;
format var1 frmt.;
run;
proc print data=raw_frmt noobs; run;
/* 5) load raw data set to CAS + apply SAS only format to CAS table <><><><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) load raw to CAS */
proc casutil;
load
data=raw
outcaslib='CASuser' /* << always implicit via sessopts=(caslib='CASuser')*/
casout='raw_cas' replace;
quit;
/* ########## re-run 2a) to validate format does NOT exist in CAS
Result: NOTE: No format libraries were found */
/* ########## re-run 3a) to validate no .sashdat files exist at all
Result: none */
/* b) apply SAS format to a CAS table in a CAS DATA Step */
data CASuser.raw_cas_frmt;
set CASuser.raw_cas;
format var1 frmt.;
run;
proc print data=CASuser.raw_cas_frmt noobs; run;
/* c) apply SAS format to a CAS table in CASutil load */
proc casutil;
format var1 frmt.;
load
data=raw
outcaslib='CASuser'
casout='raw_cas_frmt' replace;
quit;
proc print data=CASuser.raw_cas_frmt noobs; run;
/* d) apply SAS format to a CAS table in a CAS fetch action */
proc cas;
table.fetch
table={caslib='CASuser' name='raw_cas'}
fetchvars={{name='var1' format='frmt.'} {name='var2'}}
index=false;
quit;
/* 6) create the same format but add casfmtlib="CASformats" + save the format as a .sashdat file <><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* a) now create the same format:
in SAS: the format already exists
... NOTE: Format FRMT is already on the library WORK.FORMATS.
in CAS: the format Library CASformats is added
... NOTE: Format library CASFORMATS added. Format search update using parameter APPEND completed */
proc format casfmtlib="CASformats"; /* <<< lib=work.formats is implicit*/
value frmt
1 = 'abc';
run;
/* ########## re-run 2a) to validate that the CAS format library + format exists
Result: NOTE: Fmtlib = CASFORMATS
Scope = Session
Fmtsearch = YES
Format = frmt */
/* ########## re-run 3a) to validate that - still - no .sashdat files exist
Result: none */
/* b) now save our new CAS format library + format to CAS as a .sashdat file
NOTE: Cloud Analytic Services saved the file frmt.sashdat in caslib CASUSER */
cas casauto savefmtlib caslib=CASuser fmtlibname=CASformats table=frmt replace;
/* ########## re-run 3a) to validate .sashdat file DOES now exist
Result: frmt.sashdat */
/* 7) now how do we know that the frmt.sashdat file actually 'contains' a format ...
.. and specifically contains the format 'frmt' that we just created ?? <><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
/* NOTE: we know that a 'format' .sashdat file is different than a 'table' .sashdat file
In this section we load a 'format' .sashdat file to CAS + see the info. for that table
We know that trying to print that 'format' table will give us:
ERROR: Invalid characters were present in the data
Yes, an execercise in futility, BUT ...
We want to know the difference between our frmt.sashdat file and a random .sashdat file that is NOT 'tied to' any actual format */
/* a) load the frmt.sashdat file to a CAS table */
proc cas;
table.loadTable
caslib='CASuser'
path="frmt.sashdat"
importoptions={filetype="hdat"}
casout={caslib='CASuser' name="frmt_table" replace=true} ;
run;
/* b) 'see' the info. for that table */
proc cas;
table.tableinfo /
caslib='CASuser' name='frmt_table';
quit;
/* Source Name: frmt.sashdat
Source Caslib: CASUSER */
/* c) but we can create any random .sashdat format file that is NOT 'tied to' any actual format */
cas casauto savefmtlib caslib=CASuser fmtlibname=CASformats table=frmt_test replace;
/* NOTE: Cloud Analytic Services saved the file frmt_test.sashdat in caslib CASUSER.
However, frmt_test.sashdat is not 'tied to' any actual format */
/* >> load the file to a CAS table */
proc cas;
table.loadTable
caslib='CASuser'
path="frmt_test.sashdat"
importoptions={filetype="hdat"}
casout={caslib='CASuser' name="frmt_test_table" replace=true} ;
run;
/* >> see the info. for that table */
proc cas;
table.tableinfo /
caslib='CASuser' name='frmt_test_table';
quit;
/* Source Name: frmt_test.sashdat
Source Caslib: CASUSER */
/* ########## re-run 3a) to see both .sashdat files
Result: frmt.sashdat
frmt_test.sashdat */
/* So what is - and how do we know - the difference between frmt.sashdat and frmt_test.sashdat ? */
/* 8) we have now started a new CAS session <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> */
cas CASauto sessopts=(caslib='CASuser');
libname CASuser cas caslib=CASuser;
/* a) we would obviously have no session format libraries (and we did nothing to promote global format libraries ) */
cas casauto listformats fmtlibname=CASFormats SCOPE=BOTH /*GLOBAL|SESSION|BOTH*/ MEMBERS;
/* ERROR: Scope=Both was specified. Format library CASFORMATS is not found in Session or Global scope. */
/* b) but we know that the frmt.sasdhat files persist */
proc cas;
table.fileinfo
caslib='CASuser';
quit;
/* frmt.sashdat + frmt_test.sashdat*/
/* c) we 'transform' the frmt.sashdat file into the CASFORMATS library which contains the format named 'frmt' */
cas casauto addfmtlib caslib=casuser fmtlibname=CASformats table=frmt;
/* NOTE: Format library CASFORMATS added. Format search update using parameter APPEND complete */
/* d) we confirm that the CASFORMATS library + format 'frmt' exist */
cas casauto listformats fmtlibname=CASFormats SCOPE=BOTH /*GLOBAL|SESSION|BOTH*/ MEMBERS;
/* NOTE: Fmtlib = CASFORMATS
Scope = Session
Fmtsearch = YES
Format = frmt */
/* e) re-run our raw data */
data raw;
infile datalines;
input var1 var2;
datalines;
1 10
2 10
;
/* f) load raw to CAS */
proc casutil;
load
data=raw
outcaslib='CASuser' /* << always implicit via sessopts=(caslib='CASuser')*/
casout='raw_cas' replace;
quit;
/* 9) So what do we need to do to use frmt.sashdat as a format in CAS ??? <><><><><><><><><><><><><><><><><><><><><>
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
NOTE: offering a solution wherein we 'restate' the entire proc format seems to entirely disregard the idea of using a
persisted .sashdat 'format' file to apply a format in CAS
.. and would bring us back to 'argument' 5b/c/d)
... wherein we can "apply the SAS format to a CAS table" */
/* a) this provides a 'promising' note but does not seem to have an impact */
proc format casfmtlib='CASformats';
/* NOTE: Both CAS based formats and catalog-based formats will be written.
The CAS based formats will be written to the session CASAUTO. */
/* b) I don't believe that - for this excercise- we're concerned with promoting the format library to global scope */
cas casauto promotefmtlib fmtlibname=CASformats replace;
/* NOTE: Request to PROMOTEFMTLIB CASFORMATS completed for session CASAUTO.*/
/* c) note sure what this really does .. essentially the same as 7a) */
proc casutil;
load incaslib="CASuser" casdata="frmt.sashdat" outcaslib='CASuser' casout="frmt_table" replace;
quit;
/* NOTE: Cloud Analytic Services made the file frmt.sashdat available as table FRMT_TABLE in caslib CASUSER. */
/* But none of these result in our ability to use that persisted frmt.sashdat as a format in CAS */
/* >>> apply CAS format to a CAS table in a CAS DATA Step */
data CASuser.raw_cas_frmt;
set CASuser.raw_cas;
format var1 frmt.;
run;
proc print data=CASuser.raw_cas_frmt noobs; run;
/* NOTE .... Format FRMT was not found or could not be loaded. */
/* >>> apply SAS format to a CAS table in CASutil load */
proc casutil;
format var1 frmt.;
load
data=raw
outcaslib='CASuser'
casout='raw_cas_frmt' replace;
quit;
proc print data=CASuser.raw_cas_frmt noobs; run;
/* >>> apply SAS format to a CAS table in a CAS fetch action */
proc cas;
table.fetch
table={caslib='CASuser' name='raw_cas'}
fetchvars={{name='var1' format='frmt.'} {name='var2'}}
index=false;
quit;
... View more