forked from chris-swenson/sasmacros
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrenamevars.sas
178 lines (143 loc) · 6.4 KB
/
renamevars.sas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
%macro RenameVars(inds,outds,filter,test=N) / des='Rename variables in data set';
/********************************************************************************
BEGIN MACRO HEADER
********************************************************************************
Name: RenameVars.sas
Author: Chris Swenson
Created: 2009-06-25
Purpose: Rename variables within a data set based on specifications. Please
note that this macro overwrites the specified data set. A backup is
created in work with "_backup" appended to the specified data set name.
(W)ARNING: This macro overwrites the specified data set in the first argument
with specified variables renamed.
Arguments: inds - Any data set with variables matching those in the RenameVars
data set.
outds - Output data set with renamed variables. The input can be used.
filter - Text to filter the RenameVars data set.
test - Flag to indicate whether or not to test the macro.
Dependency: A data set in work named "RenameVars" is required to exist. The
data set should have the following variables: Source, Target, Filter.
Source is the original variable name, Target is the name to be used
to rename the source variable, and Filter is the criteria to match
when using the macro.
Revisions
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Date Author Comments
¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯
2010-08-02 CAS Heavy revisions to make the process more global and avoid
issues with overwriting data (unless desired).
YYYY-MM-DD III Please use this format and insert new entries above
/********************************************************************************
END MACRO HEADER
********************************************************************************/
/********************************************************************************
Settings
********************************************************************************/
%let test=%upcase(&test);
/* Check Arguments */
%if "&inds"="" %then %do;
%put %str(E)RROR: No input data set specified (argument 1).;
%return;
%end;
%if "&outds"="" %then %do;
%put %str(E)RROR: No output data set specified (argument 2).;
%return;
%end;
%if "&filter"="" %then %do;
%put %str(E)RROR: No filter specified (argument 3).;
%return;
%end;
%if %index(*Y*N*,*&TEST*)=0 %then %do;
%put %str(E)RROR: %str(I)nvalid value for the test argument. Please use Y or N.;
%return;
%end;
/* Check for RenamVars data set */
%if %sysfunc(exist(renamevars))=0 %then %do;
%put %str(E)RROR: The RenameVars data set does not exist.;
%return;
%end;
/********************************************************************************
Generate Remapping Code
********************************************************************************/
/* Filter specifications based on system and table source */
data _filter_;
set RenameVars;
/* Filter specs based on system and table */
where upcase(filter)=upcase("&filter")
and not missing(source)
and not missing(target)
;
run;
/* Output the contents of the specified data set */
proc contents data=&inds out=_contents_(keep=name) noprint varnum;
run;
proc sort data=_contents_;
by name;
run;
/* Create mapping table by left joining the contents of the data set with the specifications */
proc sql;
create table _mapping_ as
select distinct c.name as source, s.target
from _contents_ c inner join _filter_ s
on upcase(c.name)=upcase(s.source)
;
quit;
/* Create rename expression (rexpr), used to populate the PROC DATASETS rename statement */
data _mapping_;
set _mapping_;
/* Concatenate the source variable with an equal sign and the target variable */
rexpr=compress(source||'='||target);
/* Clear the labels on all variables */
attrib _all_ label='';
run;
/* Load rename expression into a macro variable */
%local mapto;
%let mapto=;
proc sql noprint;
select rexpr
into :mapto separated by " "
from _mapping_
;
quit;
/* Find the setting for quote length maximum */
%let user_quotelenmax=%sysfunc(getoption(quotelenmax));
/* Turn off quote length max message briefly */
options noquotelenmax;
/* Check the MapTo macro variable */
%if "&mapto"="" %then %do;
%put %str(W)ARNING: The table does not contain any variables listed in the RenameVars data set to rename.;
%goto exit;
%end;
%put NOTE: MAPTO=&MAPTO;
/********************************************************************************
Output and Rename
********************************************************************************/
/* Copy data set to destination */
%if &inds ne &outds %then %do;
data &outds;
set &inds;
run;
%end;
/* Drop temporary tables */
%if &test=N %then %do;
proc sql;
drop table _filter_ table _mapping_ table _contents_;
quit;
%end;
/* Rename variables to match specifications */
proc datasets nolist nodetails;
modify &outds;
/* Rename variables */
rename &mapto;
/* Remove all labels - Note: The attrib statement works although it is red in the editor. -- CAS */
attrib _all_ label='';
run;
quit;
/* Reset options to original settings */
%exit:
options &user_quotelenmax;
%put NOTE: Options changed to &user_quotelenmax..;
/********************************************************************************
END OF MACRO
********************************************************************************/
%mend RenameVars;