mirror of
https://github.com/sasjs/core.git
synced 2026-01-15 04:20:05 +00:00
feat: update to makedata to respect primary keys (and enable joins to other tables)
This commit is contained in:
90
all.sas
90
all.sas
@@ -1532,6 +1532,45 @@ Usage:
|
|||||||
%else %do;1%end;
|
%else %do;1%end;
|
||||||
|
|
||||||
%mend mf_isint;/**
|
%mend mf_isint;/**
|
||||||
|
@file
|
||||||
|
@brief Checks whether a string follows correct library.dataset format
|
||||||
|
@details Many macros in the core library accept a library.dataset parameter
|
||||||
|
referred to as 'libds'. This macro validates the structure of that parameter,
|
||||||
|
eg:
|
||||||
|
|
||||||
|
@li 8 character libref?
|
||||||
|
@li 32 character dataset?
|
||||||
|
@li contains a period?
|
||||||
|
|
||||||
|
It does NOT check whether the dataset exists, or if the library is assigned.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%put %mf_islibds(work.something)=1;
|
||||||
|
%put %mf_islibds(nolib)=0;
|
||||||
|
%put %mf_islibds(badlibref.ds)=0;
|
||||||
|
%put %mf_islibds(w.t.f)=0;
|
||||||
|
|
||||||
|
@param [in] libds The string to be checked
|
||||||
|
|
||||||
|
@return output Returns 1 if libds is valid, 0 if it is not
|
||||||
|
|
||||||
|
<h4> Related Macros </h4>
|
||||||
|
@li mf_islibds.test.sas
|
||||||
|
@li mp_validatecol.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mf_islibds(libds
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%local regex;
|
||||||
|
%let regex=%sysfunc(prxparse(%str(/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i)));
|
||||||
|
|
||||||
|
%sysfunc(prxmatch(®ex,&libds))
|
||||||
|
|
||||||
|
%mend mf_islibds;/**
|
||||||
@file
|
@file
|
||||||
@brief Returns physical location of various SAS items
|
@brief Returns physical location of various SAS items
|
||||||
@details Returns location of the PlatformObjectFramework tools
|
@details Returns location of the PlatformObjectFramework tools
|
||||||
@@ -7640,8 +7679,6 @@ lock &libds clear;
|
|||||||
according to the variable types and formats.
|
according to the variable types and formats.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
@li Respect PKs
|
|
||||||
@li Respect NOT NULLs
|
|
||||||
@li Consider dates, datetimes, times, integers etc
|
@li Consider dates, datetimes, times, integers etc
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@@ -7657,12 +7694,15 @@ lock &libds clear;
|
|||||||
);
|
);
|
||||||
%mp_makedata(work.example)
|
%mp_makedata(work.example)
|
||||||
|
|
||||||
@param [in] libds The empty table in which to create data
|
@param [in] libds The empty table (libref.dataset) in which to create data
|
||||||
@param [out] obs= (500) The number of records to create.
|
@param [out] obs= (500) The maximum number of records to create. The table
|
||||||
|
is sorted with nodup on the primary key, so the actual number of records may
|
||||||
|
be lower than this.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mf_getvarlen.sas
|
@li mf_getvarlen.sas
|
||||||
|
@li mf_islibds.sas
|
||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mp_getcols.sas
|
@li mp_getcols.sas
|
||||||
@li mp_getpk.sas
|
@li mp_getpk.sas
|
||||||
@@ -7674,45 +7714,59 @@ lock &libds clear;
|
|||||||
|
|
||||||
%macro mp_makedata(libds
|
%macro mp_makedata(libds
|
||||||
,obs=500
|
,obs=500
|
||||||
|
,seed=1
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%local ds1 c1 n1 i col charvars numvars;
|
%local ds1 ds2 lib ds pk_fields i col charvars numvars ispk;
|
||||||
|
|
||||||
%if %mf_nobs(&libds)>0 %then %do;
|
%if %mf_islibds(&libds)=0 %then %do;
|
||||||
|
%put &sysmacroname: Invalid libds (&libds) - should be library.dataset format;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
%else %if %mf_nobs(&libds)>0 %then %do;
|
||||||
%put &sysmacroname: &libds has data, it will not be recreated;
|
%put &sysmacroname: &libds has data, it will not be recreated;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%local ds1 c1 n1;
|
/* set up temporary vars */
|
||||||
%let ds1=%mf_getuniquename(prefix=mp_makedata);
|
%let ds1=%mf_getuniquename(prefix=mp_makedatads1);
|
||||||
%let c1=%mf_getuniquename(prefix=mp_makedatacol);
|
%let ds2=%mf_getuniquename(prefix=mp_makedatads2);
|
||||||
%let n1=%mf_getuniquename(prefix=mp_makedatacol);
|
%let lib=%scan(&libds,1,.);
|
||||||
data &ds1;
|
%let ds=%scan(&libds,2,.);
|
||||||
|
|
||||||
|
/* grab the primary key vars */
|
||||||
|
%mp_getpk(&lib,ds=&ds,outds=&ds1)
|
||||||
|
|
||||||
|
proc sql noprint;
|
||||||
|
select pk_fields into: pk_fields from &ds1;
|
||||||
|
|
||||||
|
data &ds2;
|
||||||
if 0 then set &libds;
|
if 0 then set &libds;
|
||||||
do _n_=1 to &obs;
|
do _n_=1 to &obs;
|
||||||
&c1=repeat(uuidgen(),10);
|
|
||||||
&n1=ranuni(1)*5000000;
|
|
||||||
drop &c1 &n1;
|
|
||||||
%let charvars=%mf_getvarlist(&libds,typefilter=C);
|
%let charvars=%mf_getvarlist(&libds,typefilter=C);
|
||||||
%if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
|
%if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
|
||||||
%let col=%scan(&charvars,&i);
|
%let col=%scan(&charvars,&i);
|
||||||
&col=subpad(&c1,1,%mf_getvarlen(&libds,&col));
|
/* create random value based on observation number and colum length */
|
||||||
|
&col=substr(put(md5(_n_),$hex32.),1,%mf_getvarlen(&libds,&col));
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%let numvars=%mf_getvarlist(&libds,typefilter=N);
|
%let numvars=%mf_getvarlist(&libds,typefilter=N);
|
||||||
%if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
|
%if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
|
||||||
%let col=%scan(&numvars,&i);
|
%let col=%scan(&numvars,&i);
|
||||||
&col=&n1;
|
&col=_n_;
|
||||||
%end;
|
%end;
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
proc sort data=&ds2 nodupkey;
|
||||||
|
by &pk_fields;
|
||||||
|
run;
|
||||||
|
|
||||||
proc append base=&libds data=&ds1;
|
proc append base=&libds data=&ds2;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds1;
|
drop table &ds1, &ds2;
|
||||||
|
|
||||||
%mend mp_makedata;/**
|
%mend mp_makedata;/**
|
||||||
@file
|
@file
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
according to the variable types and formats.
|
according to the variable types and formats.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
@li Respect PKs
|
|
||||||
@li Respect NOT NULLs
|
|
||||||
@li Consider dates, datetimes, times, integers etc
|
@li Consider dates, datetimes, times, integers etc
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@@ -27,12 +25,15 @@
|
|||||||
);
|
);
|
||||||
%mp_makedata(work.example)
|
%mp_makedata(work.example)
|
||||||
|
|
||||||
@param [in] libds The empty table in which to create data
|
@param [in] libds The empty table (libref.dataset) in which to create data
|
||||||
@param [out] obs= (500) The number of records to create.
|
@param [out] obs= (500) The maximum number of records to create. The table
|
||||||
|
is sorted with nodup on the primary key, so the actual number of records may
|
||||||
|
be lower than this.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuniquename.sas
|
@li mf_getuniquename.sas
|
||||||
@li mf_getvarlen.sas
|
@li mf_getvarlen.sas
|
||||||
|
@li mf_islibds.sas
|
||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mp_getcols.sas
|
@li mp_getcols.sas
|
||||||
@li mp_getpk.sas
|
@li mp_getpk.sas
|
||||||
@@ -44,44 +45,58 @@
|
|||||||
|
|
||||||
%macro mp_makedata(libds
|
%macro mp_makedata(libds
|
||||||
,obs=500
|
,obs=500
|
||||||
|
,seed=1
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%local ds1 c1 n1 i col charvars numvars;
|
%local ds1 ds2 lib ds pk_fields i col charvars numvars ispk;
|
||||||
|
|
||||||
%if %mf_nobs(&libds)>0 %then %do;
|
%if %mf_islibds(&libds)=0 %then %do;
|
||||||
|
%put &sysmacroname: Invalid libds (&libds) - should be library.dataset format;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
%else %if %mf_nobs(&libds)>0 %then %do;
|
||||||
%put &sysmacroname: &libds has data, it will not be recreated;
|
%put &sysmacroname: &libds has data, it will not be recreated;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%local ds1 c1 n1;
|
/* set up temporary vars */
|
||||||
%let ds1=%mf_getuniquename(prefix=mp_makedata);
|
%let ds1=%mf_getuniquename(prefix=mp_makedatads1);
|
||||||
%let c1=%mf_getuniquename(prefix=mp_makedatacol);
|
%let ds2=%mf_getuniquename(prefix=mp_makedatads2);
|
||||||
%let n1=%mf_getuniquename(prefix=mp_makedatacol);
|
%let lib=%scan(&libds,1,.);
|
||||||
data &ds1;
|
%let ds=%scan(&libds,2,.);
|
||||||
|
|
||||||
|
/* grab the primary key vars */
|
||||||
|
%mp_getpk(&lib,ds=&ds,outds=&ds1)
|
||||||
|
|
||||||
|
proc sql noprint;
|
||||||
|
select pk_fields into: pk_fields from &ds1;
|
||||||
|
|
||||||
|
data &ds2;
|
||||||
if 0 then set &libds;
|
if 0 then set &libds;
|
||||||
do _n_=1 to &obs;
|
do _n_=1 to &obs;
|
||||||
&c1=repeat(uuidgen(),10);
|
|
||||||
&n1=ranuni(1)*5000000;
|
|
||||||
drop &c1 &n1;
|
|
||||||
%let charvars=%mf_getvarlist(&libds,typefilter=C);
|
%let charvars=%mf_getvarlist(&libds,typefilter=C);
|
||||||
%if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
|
%if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
|
||||||
%let col=%scan(&charvars,&i);
|
%let col=%scan(&charvars,&i);
|
||||||
&col=subpad(&c1,1,%mf_getvarlen(&libds,&col));
|
/* create random value based on observation number and colum length */
|
||||||
|
&col=substr(put(md5(_n_),$hex32.),1,%mf_getvarlen(&libds,&col));
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%let numvars=%mf_getvarlist(&libds,typefilter=N);
|
%let numvars=%mf_getvarlist(&libds,typefilter=N);
|
||||||
%if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
|
%if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
|
||||||
%let col=%scan(&numvars,&i);
|
%let col=%scan(&numvars,&i);
|
||||||
&col=&n1;
|
&col=_n_;
|
||||||
%end;
|
%end;
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
proc sort data=&ds2 nodupkey;
|
||||||
|
by &pk_fields;
|
||||||
|
run;
|
||||||
|
|
||||||
proc append base=&libds data=&ds1;
|
proc append base=&libds data=&ds2;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
drop table &ds1;
|
drop table &ds1, &ds2;
|
||||||
|
|
||||||
%mend mp_makedata;
|
%mend mp_makedata;
|
||||||
Reference in New Issue
Block a user