🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Quartz | Level 8

## Specifying array length in do statement

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;``````

1 ACCEPTED SOLUTION

Accepted Solutions
Opal | Level 21

The syntax is

do z = 1 to 11;

PG
4 REPLIES 4
Opal | Level 21

The syntax is

do z = 1 to 11;

PG
Quartz | Level 8

## Re: Specifying array length in do statement

Thank you! This did the trick. Any idea why when I specified this way (z=1 to z=11) earlier in my code I did not encounter any problems? Are there instances when one should specify in this way?
Barite | Level 11

## Re: Specifying array length in do statement

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;``````

Super User

## Re: Specifying array length in do statement

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.

Discussion stats
• 4 replies
• 490 views
• 2 likes
• 4 in conversation