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"
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
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.