Hello,
I'm wondering why this doesn't work:
data test;
set meta;
by container:;
array container $ container:;
do i=1 to dim(container);
if nliteral('last.'||strip(vname(container(i))))=1 then output;
end;
run;
I get the following warnings/notes when I it the this way:
But this works fine:
data test;
set meta;
by container:;
array container $ container:;
if 'last.container1'N then output;
run;
It looks like the first way resolves the same way as the second method, but then isn't accepted. Is there another step I need to take with this?
The dataset is basically a series of GTL containers where I want to loop from container4 back to container1. If the container is non-missing and is the last. of it's variable then I want to run specific code. I don't know how many containers the dataset has so I'm trying to use loop logic to make it easier. I can do this with macros but wanted to see if I can make it work with just the data step.
NLITERAL is returning a string hence the conversion message. You might get somewhere with VVALUEX(nliter...) but I think you really need an array of last variables.
proc sort data=sashelp.class out=class;
by age sex;
run;
data test;
set class;
by age sex;
array _last last:;
put _last[*];
do i = 1 to dim(_last);
if _last[i] then output;
end;
run;
proc print;
run;
Please be kind enough, for this problem and all future problems, to show us the ENTIRE log for this data step (not selected parts, not just the parts you want to show us, but the ENTIRE log for this data step). In particular, we don't know what line 41 is if you just show us parts of the log.
Please copy the log as text, and paste it into the window that appears when you click on the </> icon. DO NOT SKIP THIS STEP.
First of all, no need to be condescending when you're not adding any information valid to the question at hand. I gave all of the information needed and the part of the log is the only item relevant to the question. If you really want to see the whole log for some reason and want to see the logical reason why I did not copy the entire thing, here you go. The issue is caused the the exact item that I was asking the question about to begin with and I prefer not to take up an entire monitor screen to show unnecessary information.
The primary question again is: why does 'last.container1'N work but nliteral('last.container1') not work?
1 %_eg_hidenotesandsource; 5 %_eg_hidenotesandsource; 33 34 35 data test; 36 set meta; 37 by container:; 38 39 array container $ container:; 40 do i=1 to dim(container); 41 if nliteral('last.'||strip(vname(container(i))))=1 then output; 42 *if 'last.container1'N then output; 43 end; 44 run; NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column). 41:12 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=INIT container1=BEGINGRAPH1 container2= container3= container4= Panel=0 ID=0 function1=BEGINGRAPH function2= function3= req1= req2= op1=DESIGNHEIGHT=10in opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=1 LAST.container1=0 FIRST.container2=1 LAST.container2=1 FIRST.container3=1 LAST.container3=1 FIRST.container4=1 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=1 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=INIT container1=BEGINGRAPH1 container2=LATTICE1 container3= container4= Panel=0 ID=0 function1=LATTICE function2= function3= req1= req2= op1= opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=1 LAST.container2=0 FIRST.container3=1 LAST.container3=1 FIRST.container4=1 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=2 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=addPanel container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4= Panel=0 ID=0 function1=LATTICE function2= function3= req1= req2= op1=ROWS=2 opt2=COLUMNDATARANGE=UNION opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=1 LAST.container3=0 FIRST.container4=1 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=3 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=COLUMNAXES1 Panel=0 ID=0 function1=COLUMNAXES function2= function3= req1= req2= op1= opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=1 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=4 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=COLUMNAXES1 Panel=0 ID=1 function1=COLUMNAXIS function2= function3= req1= req2= op1=Type=Linear opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 2 The SAS System 10:40 Wednesday, February 7, 2024 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=5 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=COLUMNAXES1 Panel=0 ID=1 function1=COLUMNAXIS function2=LINEAROPTS function3= req1= req2= op1=MINORTICKS=TRUE opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=6 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=addPanel container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY1 Panel=1 ID=0 function1=OVERLAY function2= function3= req1= req2= op1=WALLDISPLAY=none opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=1 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=7 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY1 Panel=1 ID=0 function1=OVERLAY function2=YAXISOPTS function3= req1= req2= op1=Type=Linear opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=8 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY1 Panel=1 ID=0 function1=OVERLAY function2=YAXISOPTS function3=LINEAROPTS req1= req2= op1=MINORTICKS=TRUE opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=9 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=scatter container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY1 Panel=1 ID=1 function1=SCATTER function2= function3= req1=X=xvar req2=y=yvar op1=group=groupvar opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=10 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=scatter container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY1 Panel=1 ID=1 function1=SCATTER function2=MARKERATTRS function3= req1= req2= op1=Symbol=circleFilled opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=11 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. 3 The SAS System 10:40 Wednesday, February 7, 2024 NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=addPanel container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=0 function1=OVERLAY function2= function3= req1= req2= op1=WALLDISPLAY=none opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=1 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=12 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=0 function1=OVERLAY function2=YAXISOPTS function3= req1= req2= op1=Type=Linear opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=13 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=0 function1=OVERLAY function2=YAXISOPTS function3=LINEAROPTS req1= req2= op1=MINORTICKS=TRUE opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=14 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=scatter container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=1 function1=SCATTER function2= function3= req1= req2= op1=X=xvar opt2=y=yvar opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=15 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=scatter container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=1 function1=SCATTER function2=MARKERATTRS function3= req1= req2= op1=Symbol=circleFilled opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=16 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=series container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=2 function1=SERIES function2= function3= req1= req2= op1=X=xvar opt2=y=yvar opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=17 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=series container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=OVERLAY2 Panel=2 ID=2 function1=SERIES function2=LINEATTRS function3= req1= req2= op1=Pattern=SOLID opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= 4 The SAS System 10:40 Wednesday, February 7, 2024 opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=1 _I_=. i=5 _ERROR_=1 _N_=18 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=SIDEBAR1 Panel=0 ID=0 function1=SIDEBAR function2= function3= req1= req2= op1=Align=RIGHT opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=1 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=19 NOTE: Invalid numeric data, '"last.container1"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container2"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container3"N' , at line 41 column 12. NOTE: Invalid numeric data, '"last.container4"N' , at line 41 column 12. WARNING: Limit set by ERRORS= option reached. Further errors of this type will not be printed. Macro=linearAxis container1=BEGINGRAPH1 container2=LATTICE1 container3=LATTICE2 container4=SIDEBAR1 Panel=0 ID=1 function1=ENTRY function2= function3= req1= req2= op1="Label Text" opt2= opt3= op2= opt4= opt5= op3= opt6= opt7= op4= opt8= opt9= op5= opt10= opt11= op6= opt12= opt13= op7= opt14= opt15= op8= opt16= FIRST.container1=0 LAST.container1=0 FIRST.container2=0 LAST.container2=0 FIRST.container3=0 LAST.container3=0 FIRST.container4=0 LAST.container4=0 _I_=. i=5 _ERROR_=1 _N_=20 NOTE: There were 22 observations read from the data set WORK.META. NOTE: The data set WORK.TEST has 0 observations and 36 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.00 seconds 45 46 %_eg_hidenotesandsource; 60 61 62 %_eg_hidenotesandsource; 65
NLITERAL is returning a string hence the conversion message. You might get somewhere with VVALUEX(nliter...) but I think you really need an array of last variables.
proc sort data=sashelp.class out=class;
by age sex;
run;
data test;
set class;
by age sex;
array _last last:;
put _last[*];
do i = 1 to dim(_last);
if _last[i] then output;
end;
run;
proc print;
run;
Thank you for pointing me towards the VVALUEX function. I was not aware of this function before. I was able to make it work with a slight modification:
if input(vvaluex('last.'||strip(vname(container(i)))),12.0)=1 then output;
Thank you much!
@JeffMeyers wrote:
Thank you for pointing me towards the VVALUEX function. I was not aware of this function before. I was able to make it work with a slight modification:
if input(vvaluex('last.'||strip(vname(container(i)))),12.0)=1 then output;
Thank you much!
Glad you got it working. You really should consider the array of LAST variables as I believe it does the same thing you are doing in more direct way. Plus, you don't have to know anything about the BY variables and the BY variables can be a mixture of character and numeric as in my example BY AGE SEX.
Your two statements are not at all structurally the same.
In the working statement:
if 'last.container1'N then output;
you are testing if a variable is TRUE or FALSE.
In the non-working statement:
if nliteral('last.'||strip(vname(container(i))))=1 then output;
you are testing if the output of a character function is equal to the number 1. Looks like SAS decided it needed to convert the generated string into a number to do the comparison. And since the output of NLITERAL() for a value that contains at least one illegal character, a period, is always going to start with a quote character SAS cannot convert that into a number to compare.
Is there any reason why you would want to run this data step? On the surface it seems extremely silly. If you have two BY variables you will get some observations duplicated. If you have three BY variables you will get some observations written three times.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.