BookmarkSubscribeRSS Feed
xtc283x
Quartz | Level 8

I've never been a sophisticated array statement processor. Regardless, I've inherited some SAS code that contains the following statements:

      data test(keep=keyno %names);set junk;

       length nexus11 nexus12 $8 nexus21 nexus22 3;

       retain %names None Other 0;

       by keyno;

        array IndicatorMatrix{*} %names None Other;

         Nexus11=put(code_1,$charxz.);

         Nexus12=put(code_2,$charyz.);

         Nexus21=put(Nexus11,$group1z.);

         Nexus22=put(Nexus12,$group2z.);

         IndicatorMatrix{Nexus21}=1;

         IndicatorMatrix{Nexus22}=1;

        if last.keyno;

So far, so good, right? The IndicatorMatrix array statement calls a little macro named %names -- which has 56 elements -- and adds two additional variables "None" and "Other" for a total of 58 elements, correct? Then, when I run this code, I get the following error:

ERROR: Array subscript out of range at line 3 column 50.

keyno=001220832MAR-11430 age=86.849315068 code_1=07819 code_2=7295 Sex=Female FIRST.keyno=1

LAST.keyno=0 nexus11=99900000 nexus12=11113456 nexus21=61 nexus22=61 AIDSH=0 CANH=0 CANL=0 CANM=0

CANVH=0 CAREL=0 CARL=0 CARM=0 CARVH=0 CERL=0 CNSH=0 CNSL=0 CNSM=0 DDL=0 DDM=0 DIA2L=0 DIA2M=0

EYEVL=0 GENEL=0 GIH=0 GIL=0 GIM=0 HEMEH=0 HEML=0 HEMM=0 HEMVH=0 HIVM=0 HLTRNS=0 INFH=0 INFL=0

INFM=0 METH=0 METM=0 METVL=0 PRGCMP=0 PRGINC=0 PSYH=0 PSYL=0 PSYM=0 PSYML=0 PULH=0 PULL=0 PULM=0

PULVH=0 RENEH=0 RENL=0 RENM=0 RENVH=0 SKCL=0 SKCM=0 SKCVL=0 SKNH=0 SKNL=0 SKNVL=0 SUBL=0 SUBVL=0

None=0 Other=0 _ERROR_=1 _N_=1

NOTE: The SAS System stopped processing this step because of errors.

NOTE: There were 2 observations read from the data set WORK.JUNK.

WARNING: The data set WORK.TEST may be incomplete.  When this step was stopped there were 0

         observations and 57 variables.

When I count the number of elements in the %names macro call, I get 56. If you count the elements dumped out in the error statement, you get 58 elements applied to the IndicatorMatrix array. The {*} is the problem, it would seem. Somehow it's returning the wrong number of elements.

I've tried everything I can think of to get this code to work. Nothing has. I don't see what I'm doing wrong.

Any suggestions as to how to fix this?

Thanks!

6 REPLIES 6
Kurt_Bremser
Super User

The array is populated with the result of %names and None/Other, which adds up, according to your description, to 58. nexus21 and nexus22 contain the value 61, which is too large for the array. So IMO the error lies in the calculation of those two variables.

The 57 variables in the output data set are determined by the keep option.

xtc283x
Quartz | Level 8

Interesting! The values of 61 for Nexus21 and Nexus22 are counts? I thought they were the resolved values of the format and put statements for Nexus11 and Nexus12...

This may have diagnosed the problem. What's the solution? How do I fix it?

Thank you!

ballardw
Super User

This line

length nexus11 nexus12 $8 nexus21 nexus22 3;

Makes the variables nexus21 and nexus22 as numeric.

You don't describe the formats $group1z and $group2z but you would likely also be seeing character to numeric conversion messages if the fatal error hadn't occurred.

Also be very sure about the desired range of numeric variables when setting length 3.

xtc283x
Quartz | Level 8

I am getting conversion comments to the log. Length 3 for the two numeric fields is fine as these are 0,1 dummies.

Does this mean that applying character formatting to numeric fields in the first two statements below is the problem?

         Nexus21=put(Nexus11,$group1z.);

         Nexus22=put(Nexus12,$group2z.);

         IndicatorMatrix{Nexus21}=1;

         IndicatorMatrix{Nexus22}=1;

Thanks!

ballardw
Super User

That is what is causing the conversion warning. You'll have to check to see that the resolved values is as desired. A possible solution is to have a custom INVALUE informat and use Nexus21 = Input(Nexus11,group1z.); Since the INVALUE should be a numeric the warning would go away.

OR Nexus21 = input(put(Nexus11,$group1z.), best.);

xtc283x
Quartz | Level 8

Ok, thanks to all for their suggestions. The sly devils that created the %macro names and the format used in the put statements had them out of sync in terms of their element counts....they were just trying to confuse us mere mortals and protect the IP of their program.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 2158 views
  • 6 likes
  • 3 in conversation