I am fairly new to SAS and am still learning nuances. The first snippet of code below runs; however, when I change the "do" line to "do z=1 to z=11;" the code no longer runs. I had done this in a previous section of my code and it worked fine, but not here. Can anyone explain why this is the case? I hope to figure this out because this seems to be the problem preventing me from running the second code snippet where I want to do one things for the first 11 elements and another thing for the additional 10 elements (Second code snippet shows what I ultimately hope to do).
Snippet 1:
length var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 $3.;
array varin raw1 raw2 raw3 raw4 raw5 raw6 raw7 raw8 raw9 raw10 raw11;
array varout var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11;
do z=1 to dim(varin);
if varin[z] ~in(. 0) then do;
varout[z] = put(varin[z], 3.);
end;
else do;
varout[z] = "";
end;
end;
This is ultimately what I hope to be able to do:
Snippet 2:
length var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 $3.;
length cnt1 cnt2 cnt3 cnt4 cnt5 cnt6 cnt7 cnt8 cnt9 cnt10 $2.;
array varin raw1 raw2 raw3 raw4 raw5 raw6 raw7 raw8 raw9 raw10 raw11 ctraw1 ctraw2 ctraw3 ctraw4 ctraw5 ctraw6 ctraw7 ctraw8 ctraw9 ctraw10;
array varout var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 cnt1 cnt2 cnt3 cnt4 cnt5 cnt6 cnt7 cnt8 cnt9 cnt10;
do z=1 to z=11;
if varin[z] ~in(. 0) then do;
varout[z] = put(varin[z], 3.);
end;
else do;
varout[z] = "";
end;
end;
do z=12 to z=21;
if varin[z] ~=. then do;
varout[z] = put(varin[z], 2.);
end;
else do;
varout[z] = "";
end;
end;
The syntax is
do z = 1 to 11;
A logical expression resolves to 1 for true and 0 for false
So your loop code as
DO Z = 1 to Z = 11;
is compiled as
DO Z = 1 to (Z=11);
which logical expression evaluation is
DO Z = 1 to 0;
and will perform 0 iterations because to stop value is less than the start value (with a tacit BY 1
)
The termination value of a DO loop is computed one time as program flow reaches the DO statement. The only way to get a 'single' step is if (Z=11) is true, which would resolve to 1, which can only happen if Z is 11 just prior to the DO loop.
You would not likely see this form top of loop is 0 or 1 per some logic expression. An obfuscatorial or job security coding mind-set might code
do index = 1 to <logic-expression>;
* statements;
end;
When this is more appropriate
if <logic-expression> then do;
* statements;
end;
You may on occasion see the top computed once feature of the DO LOOP in effect in a DOW loop over group.
DO _N_ = 1 by 1 until (last.ID);
set have;
by ID;
* x = group level computation;
end;
DO _N_ = 1 to _N_; /* top of this DO loop is _N_ value from prior DO loop */
set have;
output; * computed x value now available to every row in group;
end;
Doesn't run is awful vague.
Are there errors in the log?: Post the code and log in a code box opened with the <> to maintain formatting of error messages.
No output? Post any log in a code box.
Unexpected output? Provide input data in the form of data step code pasted into a code box, the actual results and the expected results. Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the <> icon or attached as text to show exactly what you have and that we can test code against.
Your array only has 11 elements. So when you start with Z=11 then it will only process the 11th skipping 1 through 10, raw11 and assign, possibly, a value to var11.
Your
else do;
varout[z] = "";
end;
Is not needed unless varout[z] already has a value. If you do not assign a value the variable will have a missing value.
Without specific values it is hard to be sure but with your put statement using two different formats you have a potential of creating values with a leading space. The Put with a value of 2 and format of 3. by default will create a value of " 2". If you don't want leading spaces in that case you may want to use the option in the Put of -L to left justify the result. Put(var, 3. -L) for example.
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 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.
Ready to level-up your skills? Choose your own adventure.