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_getcols.sas
40 @li mp_getpk.sas
41
42 <h4> Related Macros </h4>
43 @li mp_makedata.test.sas
44
45 @version 9.2
46 @author Allan Bowe
47
48**/
49
50%macro mp_makedata(libds
51 ,obs=500
52 ,seed=1
53)/*/STORE SOURCE*/;
54
55%local ds1 ds2 lib ds pk_fields i col charvars numvars ispk;
56
57%if %mf_islibds(&libds)=0 %then %do;
58 %put &sysmacroname: Invalid libds (&libds) - should be library.dataset format;
59 %return;
60%end;
61%else %if %mf_nobs(&libds)>0 %then %do;
62 %put &sysmacroname: &libds has data, it will not be recreated;
63 %return;
64%end;
65
66/* set up temporary vars */
67%let ds1=%mf_getuniquename(prefix=mp_makedatads1);
68%let ds2=%mf_getuniquename(prefix=mp_makedatads2);
69%let lib=%scan(&libds,1,.);
70%let ds=%scan(&libds,2,.);
71
72/* grab the primary key vars */
73%mp_getpk(&lib,ds=&ds,outds=&ds1)
74
75proc sql noprint;
76select coalescec(pk_fields,'_all_') into: pk_fields from &ds1;
77
78data &ds2;
79 if 0 then set &libds;
80 do _n_=1 to &obs;
81 %let charvars=%mf_getvarlist(&libds,typefilter=C);
82 %if &charvars ^= %then %do i=1 %to %sysfunc(countw(&charvars));
83 %let col=%scan(&charvars,&i);
84 /* create random value based on observation number and colum length */
85 &col=repeat(put(md5(cats(_n_)),$hex32.),%mf_getvarlen(&libds,&col)/32);
86 %end;
87
88 %let numvars=%mf_getvarlist(&libds,typefilter=N);
89 %if &numvars ^= %then %do i=1 %to %sysfunc(countw(&numvars));
90 %let col=%scan(&numvars,&i);
91 &col=_n_;
92 %end;
93 output;
94 end;
95 stop;
96run;
97proc sort data=&ds2 nodupkey;
98 by &pk_fields;
99run;
100
101proc append base=&libds data=&ds2;
102run;
103
104proc sql;
105drop table &ds1, &ds2;
106
107%mend mp_makedata;