I have a Dataset (It's the MXG ASUM70PR) that stores it's data in wide format. I want to convert it to narrow format using PROC TRANSPOSE, but the only problem is that the field names are not conducive for this routine.
I set up a macro to convert the names:
%macro set0(suff) ;
* 123456789012345678901234567890123456
%LET LPSEQ =0123456789ABCDEFGHIJKLMNOQRSTUVWXYZ;
%LET LQSEQ =123456789ABCDEFGHIJKLMNOPQ;
%put start OF LP LOOP;
%do j=1 %to 35;
%let name = LP%substr(&LPSEQ,&j,1)&suff;
%let i = %eval(&j-1);
%put &suff&I = &name ;
&suff&I = &name ;
%end;
%put start OF LQ LOOP;
%do j=1 %to 26;
%let Name = LQ%substr(&LQSEQ,&j,1)&suff;
%let i = %eval(35+&j);
%put &suff&i = &name ;
&suff&i = &name ;
%end;
%mend;
data test0 (keep = startime name0-name60);
set &PDB_DAY..asum70pr;
%set0(NAME);
proc contents;
proc print;
But the field NAME0 does not appear in the resultant data set.
What am I doing wrong?
@Astounding Already gave you the answer.
Consider this test program.
%macro test;
* Comment without closing semi-colon
%let xx=macro var assignment;
data x;
set y;
run;
%mend test;
See what happens when you run it:
293 options mprint; 294 %test; MPRINT(TEST): * Comment without closing semi-colon data x; NOTE: Line generated by the invoked macro "TEST". 294 set y; --- 180 MPRINT(TEST): set y; ERROR 180-322: Statement is not valid or it is used out of proper order. MPRINT(TEST): run;
If you are really running the exact same file then check and make sure you have not truncated the ends of the lines on the "mainframe" version.
1. Paste code using the {i} or the running man icon
2. It works for me.
%macro set0(suff) ;
* 123456789012345678901234567890123456;
%let LPSEQ =0123456789ABCDEFGHIJKLMNOQRSTUVWXYZ;
%let LQSEQ =123456789ABCDEFGHIJKLMNOPQ;
%put start OF LP LOOP;
%do j=1 %to 35;
%let name = LP%substr(&LPSEQ,&j,1)&suff;
%let i = %eval(&j-1);
%put &suff&I = &name ;
&suff&I = &name ;
%end;
%put start OF LQ LOOP;
%do j=1 %to 26;
%let Name = LQ%substr(&LQSEQ,&j,1)&suff;
%let i = %eval(35+&j);
%put &suff&i = &name ;
&suff&i = &name ;
%end;
%mend;
data test0 (keep = startime name0-name60);
*set &PDB_DAY..asum70pr;
%set0(NAME);
run;
proc contents; run;
proc print; run;
Do the transpose from your original dataset.
Convert your macro code to a data step that creates a cntlin dataset for proc format.
Use the resulting format to change the _name_ column in the transposed dataset.
Code for creating the format:
data cntlin;
LPSEQ = "0123456789ABCDEFGHIJKLMNOQRSTUVWXYZ";
LQSEQ = "123456789ABCDEFGHIJKLMNOPQ";
fmtname = 'myfmt';
type = 'C';
do j = 1 to 35;
start = cats("LP",substr(LPSEQ,j,1),"NAME");
label = cats("NAME",j-1);
output;
end;
do j = 1 to 26;
start = cats('LQ',substr(LQSEQ,j,1),"NAME");
label = cats("NAME",j+35);
output;
end;
drop lqseq lpseq j;
run;
proc format cntlin=cntlin;
run;
Thanks so much for the replies.
Looks like this is a bug with the Mainframe Version of SAS. When I Run the Code on the PC It works!
I have opened a case with SAS.
@Astounding Already gave you the answer.
Consider this test program.
%macro test;
* Comment without closing semi-colon
%let xx=macro var assignment;
data x;
set y;
run;
%mend test;
See what happens when you run it:
293 options mprint; 294 %test; MPRINT(TEST): * Comment without closing semi-colon data x; NOTE: Line generated by the invoked macro "TEST". 294 set y; --- 180 MPRINT(TEST): set y; ERROR 180-322: Statement is not valid or it is used out of proper order. MPRINT(TEST): run;
If you are really running the exact same file then check and make sure you have not truncated the ends of the lines on the "mainframe" version.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.