mirror of
https://github.com/sasjs/core.git
synced 2026-01-08 01:50:05 +00:00
Merge pull request #79 from sasjs/issue78
feat: adding binary variable support to mp_ds2cards.sas
This commit is contained in:
59
all.sas
59
all.sas
@@ -3315,12 +3315,21 @@ run;
|
|||||||
@file
|
@file
|
||||||
@brief Create a CARDS file from a SAS dataset.
|
@brief Create a CARDS file from a SAS dataset.
|
||||||
@details Uses dataset attributes to convert all data into datalines.
|
@details Uses dataset attributes to convert all data into datalines.
|
||||||
Running the generated file will rebuild the original dataset.
|
Running the generated file will rebuild the original dataset. Includes
|
||||||
|
support for large decimals, binary data, PROCESSED_DTTM columns, and
|
||||||
|
alternative encoding. If the input dataset is empty, the cards file will
|
||||||
|
still be created.
|
||||||
|
|
||||||
|
Additional support to generate a random sample and max rows.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
%mp_ds2cards(base_ds=sashelp.class
|
%mp_ds2cards(base_ds=sashelp.class
|
||||||
|
, tgt_ds=work.class
|
||||||
, cards_file= "C:\temp\class.sas"
|
, cards_file= "C:\temp\class.sas"
|
||||||
, maxobs=5)
|
, showlog=NO
|
||||||
|
, maxobs=5
|
||||||
|
)
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- labelling the dataset
|
- labelling the dataset
|
||||||
@@ -3331,15 +3340,24 @@ run;
|
|||||||
that is converted to a cards file.
|
that is converted to a cards file.
|
||||||
@param [in] tgt_ds= Table that the generated cards file would create.
|
@param [in] tgt_ds= Table that the generated cards file would create.
|
||||||
Optional - if omitted, will be same as BASE_DS.
|
Optional - if omitted, will be same as BASE_DS.
|
||||||
@param [out] cards_file= Location in which to write the (.sas) cards file
|
@param [out] cards_file= ("%sysfunc(pathname(work))/cardgen.sas") Location in
|
||||||
@param [in] maxobs= to limit output to the first <code>maxobs</code>
|
which to write the (.sas) cards file
|
||||||
observations
|
@param [in] maxobs= (max) To limit output to the first <code>maxobs</code>
|
||||||
@param [in] showlog= whether to show generated cards file in the SAS log
|
observations, enter an integer here.
|
||||||
(YES/NO)
|
@param [in] random_sample= (NO) Set to YES to generate a random sample of
|
||||||
@param [in] outencoding= provide encoding value for file statement (eg utf-8)
|
data. Can be quite slow.
|
||||||
@param [in] append= If NO then will rebuild the cards file if it already
|
@param [in] showlog= (YES) Whether to show generated cards file in the SAS
|
||||||
|
log. Valid values:
|
||||||
|
@li YES
|
||||||
|
@li NO
|
||||||
|
@param [in] outencoding= Provide encoding value for file statement (eg utf-8)
|
||||||
|
@param [in] append= (NO) If NO then will rebuild the cards file if it already
|
||||||
exists, otherwise will append to it. Used by the mp_lib2cards.sas macro.
|
exists, otherwise will append to it. Used by the mp_lib2cards.sas macro.
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mp_lib2cards.sas
|
||||||
|
@li mp_ds2inserts.sas
|
||||||
|
@li mp_mdtablewrite.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -3364,7 +3382,7 @@ run;
|
|||||||
%if (&tgt_ds = ) %then %let tgt_ds=&base_ds;
|
%if (&tgt_ds = ) %then %let tgt_ds=&base_ds;
|
||||||
%if %index(&tgt_ds,.)=0 %then %let tgt_ds=WORK.%scan(&base_ds,2,.);
|
%if %index(&tgt_ds,.)=0 %then %let tgt_ds=WORK.%scan(&base_ds,2,.);
|
||||||
%if ("&outencoding" ne "") %then %let outencoding=encoding="&outencoding";
|
%if ("&outencoding" ne "") %then %let outencoding=encoding="&outencoding";
|
||||||
%if ("&append" = "") %then %let append=;
|
%if ("&append" = "" or "&append" = "NO") %then %let append=;
|
||||||
%else %let append=mod;
|
%else %let append=mod;
|
||||||
|
|
||||||
/* get varcount */
|
/* get varcount */
|
||||||
@@ -3450,6 +3468,11 @@ data datalines_2;
|
|||||||
,put(',name,',best32.-l)
|
,put(',name,',best32.-l)
|
||||||
,substrn(put(',name,',bestd32.-l),1
|
,substrn(put(',name,',bestd32.-l),1
|
||||||
,findc(put(',name,',bestd32.-l),"0","TBK")))');
|
,findc(put(',name,',bestd32.-l),"0","TBK")))');
|
||||||
|
/**
|
||||||
|
* binary data must be converted, to store in text format. It is identified
|
||||||
|
* by the presence of the $HEX keyword in the format.
|
||||||
|
*/
|
||||||
|
else if upcase(format)=:'$HEX' then dataline=cats('put(',name,',',format,')');
|
||||||
else dataline=name;
|
else dataline=name;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -3475,7 +3498,8 @@ data _null_;
|
|||||||
|
|
||||||
|
|
||||||
/* Build input statement */
|
/* Build input statement */
|
||||||
if type='char' then type3=':$char.';
|
if upcase(format)=:'$HEX' then type3=':'!!format;
|
||||||
|
else if type='char' then type3=':$char.';
|
||||||
str2=put(name,$33.)||type3;
|
str2=put(name,$33.)||type3;
|
||||||
|
|
||||||
|
|
||||||
@@ -3497,11 +3521,12 @@ data _null_;
|
|||||||
file &cards_file. &outencoding lrecl=32767 termstr=nl &append;
|
file &cards_file. &outencoding lrecl=32767 termstr=nl &append;
|
||||||
length __attrib $32767;
|
length __attrib $32767;
|
||||||
if _n_=1 then do;
|
if _n_=1 then do;
|
||||||
put '/*******************************************************************';
|
put '/**';
|
||||||
put " Datalines for %upcase(%scan(&base_ds,2)) dataset ";
|
put ' @file';
|
||||||
put " Generated by %nrstr(%%)mp_ds2cards()";
|
put " @brief Datalines for %upcase(%scan(&base_ds,2)) dataset";
|
||||||
put " Available on github.com/sasjs/core";
|
put " @details Generated by %nrstr(%%)mp_ds2cards()";
|
||||||
put '********************************************************************/';
|
put " Available on github.com/sasjs/core";
|
||||||
|
put '**/';
|
||||||
put "data &tgt_ds &indexes;";
|
put "data &tgt_ds &indexes;";
|
||||||
put "attrib ";
|
put "attrib ";
|
||||||
%do i = 1 %to &nvars;
|
%do i = 1 %to &nvars;
|
||||||
@@ -3529,7 +3554,7 @@ data _null_;
|
|||||||
put "input ";
|
put "input ";
|
||||||
%do i = 1 %to &nvars.;
|
%do i = 1 %to &nvars.;
|
||||||
%if(%length(&&input_stmt_&i..)) %then
|
%if(%length(&&input_stmt_&i..)) %then
|
||||||
put " &&input_stmt_&i..";
|
put " &&input_stmt_&i..";
|
||||||
;
|
;
|
||||||
%end;
|
%end;
|
||||||
put ";";
|
put ";";
|
||||||
|
|||||||
@@ -2,12 +2,21 @@
|
|||||||
@file
|
@file
|
||||||
@brief Create a CARDS file from a SAS dataset.
|
@brief Create a CARDS file from a SAS dataset.
|
||||||
@details Uses dataset attributes to convert all data into datalines.
|
@details Uses dataset attributes to convert all data into datalines.
|
||||||
Running the generated file will rebuild the original dataset.
|
Running the generated file will rebuild the original dataset. Includes
|
||||||
|
support for large decimals, binary data, PROCESSED_DTTM columns, and
|
||||||
|
alternative encoding. If the input dataset is empty, the cards file will
|
||||||
|
still be created.
|
||||||
|
|
||||||
|
Additional support to generate a random sample and max rows.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
%mp_ds2cards(base_ds=sashelp.class
|
%mp_ds2cards(base_ds=sashelp.class
|
||||||
|
, tgt_ds=work.class
|
||||||
, cards_file= "C:\temp\class.sas"
|
, cards_file= "C:\temp\class.sas"
|
||||||
, maxobs=5)
|
, showlog=NO
|
||||||
|
, maxobs=5
|
||||||
|
)
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- labelling the dataset
|
- labelling the dataset
|
||||||
@@ -18,15 +27,24 @@
|
|||||||
that is converted to a cards file.
|
that is converted to a cards file.
|
||||||
@param [in] tgt_ds= Table that the generated cards file would create.
|
@param [in] tgt_ds= Table that the generated cards file would create.
|
||||||
Optional - if omitted, will be same as BASE_DS.
|
Optional - if omitted, will be same as BASE_DS.
|
||||||
@param [out] cards_file= Location in which to write the (.sas) cards file
|
@param [out] cards_file= ("%sysfunc(pathname(work))/cardgen.sas") Location in
|
||||||
@param [in] maxobs= to limit output to the first <code>maxobs</code>
|
which to write the (.sas) cards file
|
||||||
observations
|
@param [in] maxobs= (max) To limit output to the first <code>maxobs</code>
|
||||||
@param [in] showlog= whether to show generated cards file in the SAS log
|
observations, enter an integer here.
|
||||||
(YES/NO)
|
@param [in] random_sample= (NO) Set to YES to generate a random sample of
|
||||||
@param [in] outencoding= provide encoding value for file statement (eg utf-8)
|
data. Can be quite slow.
|
||||||
@param [in] append= If NO then will rebuild the cards file if it already
|
@param [in] showlog= (YES) Whether to show generated cards file in the SAS
|
||||||
|
log. Valid values:
|
||||||
|
@li YES
|
||||||
|
@li NO
|
||||||
|
@param [in] outencoding= Provide encoding value for file statement (eg utf-8)
|
||||||
|
@param [in] append= (NO) If NO then will rebuild the cards file if it already
|
||||||
exists, otherwise will append to it. Used by the mp_lib2cards.sas macro.
|
exists, otherwise will append to it. Used by the mp_lib2cards.sas macro.
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mp_lib2cards.sas
|
||||||
|
@li mp_ds2inserts.sas
|
||||||
|
@li mp_mdtablewrite.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -51,7 +69,7 @@
|
|||||||
%if (&tgt_ds = ) %then %let tgt_ds=&base_ds;
|
%if (&tgt_ds = ) %then %let tgt_ds=&base_ds;
|
||||||
%if %index(&tgt_ds,.)=0 %then %let tgt_ds=WORK.%scan(&base_ds,2,.);
|
%if %index(&tgt_ds,.)=0 %then %let tgt_ds=WORK.%scan(&base_ds,2,.);
|
||||||
%if ("&outencoding" ne "") %then %let outencoding=encoding="&outencoding";
|
%if ("&outencoding" ne "") %then %let outencoding=encoding="&outencoding";
|
||||||
%if ("&append" = "") %then %let append=;
|
%if ("&append" = "" or "&append" = "NO") %then %let append=;
|
||||||
%else %let append=mod;
|
%else %let append=mod;
|
||||||
|
|
||||||
/* get varcount */
|
/* get varcount */
|
||||||
@@ -137,6 +155,11 @@ data datalines_2;
|
|||||||
,put(',name,',best32.-l)
|
,put(',name,',best32.-l)
|
||||||
,substrn(put(',name,',bestd32.-l),1
|
,substrn(put(',name,',bestd32.-l),1
|
||||||
,findc(put(',name,',bestd32.-l),"0","TBK")))');
|
,findc(put(',name,',bestd32.-l),"0","TBK")))');
|
||||||
|
/**
|
||||||
|
* binary data must be converted, to store in text format. It is identified
|
||||||
|
* by the presence of the $HEX keyword in the format.
|
||||||
|
*/
|
||||||
|
else if upcase(format)=:'$HEX' then dataline=cats('put(',name,',',format,')');
|
||||||
else dataline=name;
|
else dataline=name;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -162,7 +185,8 @@ data _null_;
|
|||||||
|
|
||||||
|
|
||||||
/* Build input statement */
|
/* Build input statement */
|
||||||
if type='char' then type3=':$char.';
|
if upcase(format)=:'$HEX' then type3=':'!!format;
|
||||||
|
else if type='char' then type3=':$char.';
|
||||||
str2=put(name,$33.)||type3;
|
str2=put(name,$33.)||type3;
|
||||||
|
|
||||||
|
|
||||||
@@ -184,11 +208,12 @@ data _null_;
|
|||||||
file &cards_file. &outencoding lrecl=32767 termstr=nl &append;
|
file &cards_file. &outencoding lrecl=32767 termstr=nl &append;
|
||||||
length __attrib $32767;
|
length __attrib $32767;
|
||||||
if _n_=1 then do;
|
if _n_=1 then do;
|
||||||
put '/*******************************************************************';
|
put '/**';
|
||||||
put " Datalines for %upcase(%scan(&base_ds,2)) dataset ";
|
put ' @file';
|
||||||
put " Generated by %nrstr(%%)mp_ds2cards()";
|
put " @brief Datalines for %upcase(%scan(&base_ds,2)) dataset";
|
||||||
put " Available on github.com/sasjs/core";
|
put " @details Generated by %nrstr(%%)mp_ds2cards()";
|
||||||
put '********************************************************************/';
|
put " Available on github.com/sasjs/core";
|
||||||
|
put '**/';
|
||||||
put "data &tgt_ds &indexes;";
|
put "data &tgt_ds &indexes;";
|
||||||
put "attrib ";
|
put "attrib ";
|
||||||
%do i = 1 %to &nvars;
|
%do i = 1 %to &nvars;
|
||||||
@@ -216,7 +241,7 @@ data _null_;
|
|||||||
put "input ";
|
put "input ";
|
||||||
%do i = 1 %to &nvars.;
|
%do i = 1 %to &nvars.;
|
||||||
%if(%length(&&input_stmt_&i..)) %then
|
%if(%length(&&input_stmt_&i..)) %then
|
||||||
put " &&input_stmt_&i..";
|
put " &&input_stmt_&i..";
|
||||||
;
|
;
|
||||||
%end;
|
%end;
|
||||||
put ";";
|
put ";";
|
||||||
|
|||||||
60
tests/crossplatform/mp_ds2cards.test.sas
Normal file
60
tests/crossplatform/mp_ds2cards.test.sas
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_ds2cards.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_ds2cards.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test 1 - rebuild an existing dataset
|
||||||
|
* Cars is a great dataset - it contains leading spaces, and formatted numerics
|
||||||
|
*/
|
||||||
|
|
||||||
|
%mp_ds2cards(base_ds=sashelp.cars
|
||||||
|
, tgt_ds=work.test
|
||||||
|
, cards_file= "%sysfunc(pathname(work))/cars.sas"
|
||||||
|
, showlog=NO
|
||||||
|
)
|
||||||
|
%inc "%sysfunc(pathname(work))/cars.sas"/source2;
|
||||||
|
|
||||||
|
proc compare base=sashelp.cars compare=work.test;
|
||||||
|
quit;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&sysinfo=1),
|
||||||
|
desc=sashelp.cars is identical except for ds label,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test 2 - binary data compare
|
||||||
|
*/
|
||||||
|
data work.binarybase;
|
||||||
|
format bin $hex500. z $hex.;
|
||||||
|
do x=1 to 250;
|
||||||
|
z=byte(x);
|
||||||
|
bin=trim(bin)!!z;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_ds2cards(base_ds=work.binarybase
|
||||||
|
, showlog=YES
|
||||||
|
, cards_file="%sysfunc(pathname(work))/c2.sas"
|
||||||
|
, tgt_ds=work.binarycompare
|
||||||
|
, append=
|
||||||
|
)
|
||||||
|
|
||||||
|
%inc "%sysfunc(pathname(work))/c2.sas"/source2;
|
||||||
|
|
||||||
|
proc compare base=work.binarybase compare=work.binarycompare;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&sysinfo=0),
|
||||||
|
desc=work.binarybase dataset is identical,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user