Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mp_makedata.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Create sample data based on the structure of an empty table
4 @details Many SAS projects involve sensitive datasets. One way to _ensure_
5 the data is anonymised, is never to receive it in the first place! Often
6 consultants are provided with empty tables, and expected to create complex
7 ETL flows.
8
9 This macro can help by taking an empty table, and populating it with data
10 according to the variable types and formats.
11
12 TODO:
13 @li Consider dates, datetimes, times, integers etc
14
15 Usage:
16
17 proc sql;
18 create table work.example(
19 TX_FROM float format=datetime19.,
20 DD_TYPE char(16),
21 DD_SOURCE char(2048),
22 DD_SHORTDESC char(256),
23 constraint pk primary key(tx_from, dd_type,dd_source),
24 constraint nnn not null(DD_SHORTDESC)
25 );
26 %mp_makedata(work.example)
27
28 @param [in] libds The empty table (libref.dataset) in which to create data
29 @param [out] obs= (500) The maximum number of records to create. The table
30 is sorted with nodup on the primary key, so the actual number of records may
31 be lower than this.
32
33 <h4> SAS Macros </h4>
34 @li mf_getuniquename.sas
35 @li mf_getvarlen.sas
36 @li mf_getvarlist.sas
37 @li mf_islibds.sas
38 @li mf_nobs.sas
39 @li mp_getpk.sas
40
41 <h4> Related Macros </h4>
42 @li mp_makedata.test.sas
43
44 @version 9.2
45 @author Allan Bowe
46
47**/
48
49%macro mp_makedata(libds
50 ,obs=500
51 ,seed=1
52)/*/STORE SOURCE*/;
53
54%local ds1 ds2 lib ds pk_fields i col charvars numvars ispk;
55
56%if %mf_islibds(&libds)=0 %then %do;
57 %put &sysmacroname: Invalid libds (&libds) - should be library.dataset format;
58 %return;
59%end;
60%else %if %mf_nobs(&libds)>0 %then %do;
61 %put &sysmacroname: &libds has data, it will not be recreated;
62 %return;
63%end;
64
65/* set up temporary vars */
66%let ds1=%mf_getuniquename(prefix=mp_makedatads1);
67%let ds2=%mf_getuniquename(prefix=mp_makedatads2);
68%let lib=%scan(&libds,1,.);
69%let ds=%scan(&libds,2,.);
70
71/* grab the primary key vars */
72%mp_getpk(&lib,ds=&ds,outds=&ds1)
73
74proc sql noprint;
75select coalescec(pk_fields,'_all_') into: pk_fields from &ds1;
76
77data &ds2;
78 if 0 then set &libds;
79 do _n_=1 to &obs;
80 %let charvars=%mf_getvarlist(&libds,typefilter=C);
81 %if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
82 %let col=%scan(&charvars,&i);
83 /* create random value based on observation number and colum length */
84 &col=repeat(put(md5(cats(_n_)),$hex32.),%mf_getvarlen(&libds,&col)/32);
85 %end;
86
87 %let numvars=%mf_getvarlist(&libds,typefilter=N);
88 %if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
89 %let col=%scan(&numvars,&i);
90 &col=_n_;
91 %end;
92 output;
93 end;
94 stop;
95run;
96proc sort data=&ds2 nodupkey;
97 by &pk_fields;
98run;
99
100proc append base=&libds data=&ds2;
101run;
102
103proc sql;
104drop table &ds1, &ds2;
105
106%mend mp_makedata;