14 proc format;
15 invalue myfmt (default=2)
16 0 = 88
17 99 = .U
18 other = _same_;
NOTE: Informat MYFMT is already on the library.
NOTE: Informat MYFMT has been output.
19 run;
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
20
21 data _null_;
22 input @1 mynum ??myfmt.
23 @1 orig $char2.
24 @3 mychar $char1.;
25 if mynum=. then mynum=.U;
26 putlog orig= mynum=;
27 cards4;
orig=0 mynum=88
orig=1 mynum=1
orig=Y mynum=U
orig=T mynum=U
orig=. mynum=U
orig=: mynum=U
orig=99 mynum=U
orig=9 mynum=9
orig=1. mynum=1
NOTE: The data set WORK.WANT has 9 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
37 ;;;;
38 run;
Thank you for the coding and output. The trick is that the macro reads in the varname, length, etc - and it would be ideal to use the varname (before it's replaced in the next iteration of the loop) while I have 'it' - to avoid hard coding later. That is, at the same time I read in a particular variable I'd like to address any _error_ issues.
May not be easy or possible.
If your macro was generating one INPUT statement you can split it up by using the trailing @.
Instead of :
#1 @003 certnum 6.
#1 @009 mm_dob monthf.
#1 @011 dd_dob 2.
Generate a complete INPUT statement with a trailing @.
input #1 @003 certnum ?6. @;
if _error_ then put 'Invalid data for variable ' "certnum" ;
_error_=0;
input #1 @009 mm_dob ?monthf. @;
if _error_ then put 'Invalid data for variable ' "mm_dob" ;
_error_=0;
14 %macro layout;
15 #1 @1 mynum1 ??myfmt.
16 #1 @3 mychar $char2.
17 #2 @5 mynum2 ??myfmt.
18 %mend;
19
20 proc format;
21 invalue myfmt (default=2)
22 0 = 88
23 99 = .U
24 other = _same_;
NOTE: Informat MYFMT is already on the library.
NOTE: Informat MYFMT has been output.
25 run;
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
26
27 data fake;
28 input %layout;
29 cards;
NOTE: The data set WORK.FAKE has 0 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
30 ;
31 run;
32
33 proc sql noprint;
34 select 'if ' !! strip(name) !! '=. then ' !! strip(name) !! '=.U' into :missing separated by '; '
35 from sashelp.vcolumn
36 where libname='WORK' and memname='FAKE' and type='num';
37 run;
NOTE: PROC SQL statements are executed immediately; The RUN statement has no effect.
38
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
2 The SAS System 10:48 Wednesday, September 7, 2011
39 data _null_;
40 input #1 @1 orig1 $2.
41 #2 @5 orig2 $2.
42 %layout;
43 &missing;
44 put orig1= mynum1= mychar= orig2= mynum2=;
45 cards;
orig1=1 mynum1=1 mychar=A orig2=9 mynum2=9
orig1=99 mynum1=U mychar=C orig2=0 mynum2=88
orig1=62 mynum1=62 mychar=E orig2=/ mynum2=U
orig1=[ mynum1=U mychar=[ orig2= mynum2=U
orig1=.A mynum1=A mychar=. orig2= mynum2=U
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
56 ;
57 run;
58
59 %put %bquote(&missing);
if mynum1=. then mynum1=.U; if mynum2=. then mynum2=.U
More documentation is available on the help page for the INPUT statement. There you can find the information on the : & and ~ in the section on Modified List Input.
Thanks to all. I was able to modify the macro to include the '?' and _error_ information.
I was a bit surprised this format
invalue u_nine (default=1)
9 = .U
other = _same_;
along with the error checking changed ' ' (blanks) to '.' (dots). I modified the format to look for blanks. I could also change the input from:
MPRINT(CREATE_INPUT_STRING_D4): input #1 @021 married ? u_nine. @;
MPRINT(CREATE_INPUT_STRING_D4): if _error_ then married=.U ;
MPRINT(CREATE_INPUT_STRING_D4): _error_=0;
to 'if married = . then married = .U' I suppose but I thought the 'if _error_' would be more robust. Or include both perhaps - look for _error_ and '.'
From no options to many - thanks again.
Anjali
Quick update - I tried including :
if _error_ or &varname = . then &varname = .U
but it blew up for some of my character variables.
I'll eliminate the "or &varname=.' and find another way to deal with blank values. Or make a more complex conditional check based on var type.
I haven't kept up with the entire thread, thus don't know exactly what you are trying to do, but you are trying to assign a value to a macro variable. You won't be able to use that macro variable in the same datastep anyhow but, if that is what you need to do (i.e., assign a value to a macro variable), use call symput.
14 %macro layout;
15 #1 @1 mynum1 ??myfmt.
16 #1 @3 mychar $char2.
17 #2 @3 mynum2 ??myfmt.
18 %mend;
19
20 proc format;
21 invalue myfmt (default=2)
22 0 = 88
23 99 = .U
24 other = _same_;
NOTE: Informat MYFMT is already on the library.
NOTE: Informat MYFMT has been output.
25 run;
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
26
27 data fake;
28 input %layout;
29 cards;
NOTE: The data set WORK.FAKE has 0 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
30 ;
31 run;
32
33 proc sql noprint;
34 select 'if ' !! strip(name) !! '=. then ' !! strip(name) !! '=.U' into :missingn separated by '; '
35 from sashelp.vcolumn
36 where libname='WORK' and memname='FAKE' and type='num';
37 select 'if ' !! strip(name) !! '="" then ' !! strip(name) !! '="U"' into :missingc separated by '; '
38 from sashelp.vcolumn
39 where libname='WORK' and memname='FAKE' and type='char';
40 run;
NOTE: PROC SQL statements are executed immediately; The RUN statement has no effect.
41
2 The SAS System 09:36 Thursday, September 8, 2011
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
42 data _null_;
43 input #1 @1 orig1 $2.
44 #2 @3 orig2 $2.
45 %layout;
46 &missingn;
47 &missingc;
48 put orig1= mynum1= mychar= orig2= mynum2=;
49 cards;
orig1=1 mynum1=1 mychar=A orig2=9 mynum2=9
orig1=99 mynum1=U mychar=C orig2=88 mynum2=88
orig1=62 mynum1=62 mychar=E orig2=/ mynum2=U
orig1=[ mynum1=U mychar=[ orig2=}} mynum2=U
orig1=.A mynum1=A mychar=. orig2=.C mynum2=C
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
60 ;
61 run;
62
63 %put NOTE: Missingn == %bquote(&missingn);
NOTE: Missingn == if mynum1=. then mynum1=.U; if mynum2=. then mynum2=.U
64 %put NOTE: Missingc == %bquote(&missingc);
NOTE: Missingc == if mychar="" then mychar="U"
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.