BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Lulus
Obsidian | Level 7

Thank you all for kind help in advance.

I've got this error message which stops the SAS calculation. 

NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).

ERROR: Array subscript out of range at line ~ column ~.   (~'s replace actual numbers)

set stdff;

  array coding2 {*} agroup_1-agroup_6;

  do i=1 to 6;

  coding2(i)=0;

  array coding3 {*} boys girls notdisclose nodata;

  do j=1 to 4;

  coding3(j)=0;

  array coding4 {*} salary1-salary6 salary7;

  do k=1 to 7;

  coding4(k)=0;

  end;

  coding4(income_dx)=1;    <-------------------------------Error Happens Here!! Need help!!

  end;

  coding3(gndr_dx)=1;

  end;

  coding2(ETHG_dx)=1;

drop i j k;

run;

So, a little more information, I had a draft code I wrote myself which has no problem running.  In the draft code, the salary elements were labeled salary1-salary10.

later on we decided to combined some of the salary levels so it became 6 levels plus one missing value label (which is the salary7).

So, old codes are no problem. 

Another thing, if you just remove the most inner loop, the rest runs fine as well. 

Please let me know what happens in the most inner part.  Is that some kind of do-loop iteration problems? 

I've done

1. change coding4 labels to (salary1 salary2 salary3 salary4.....  one by one listing), even name elements after 7 dwarfs so make sure no numbers in there.

2. add {7} in the { }

3. gave length to 3

4. do k =1 to 6, do k=1 to 8

none of them work.

Please help!!  Greatly Thanks!!

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

Hi:

  A simple number without punctuation should convert correctly. The problem that I see, is when you say that INCOME_DX can possibly have a value of 9, but you have defined your CODING4 array to only have 7 elements, so a value for 9 will be considered "out of range".

cynthia

View solution in original post

21 REPLIES 21
TimArm
Obsidian | Level 7

What's the value of income_dx (or gndr_dx or ETHG_dx for that matter).

At the point of the error you are outside of the do loop, so the value of k is irrelevant.

Lulus
Obsidian | Level 7

The income_dx, gndr_dx and ethg_dx are all categorical variables indexing income levels (1,2,3,4,5,6 and 7 for missing), sex (boys, girls....) and sports group (1 2 3 4.....).

In the income_dx variables.  1 means you make less than 30,000 a year and so on.......... 6 probably means 400K+ or something (I have to refer a doc. which says that all).

I also checked in the frequcy tables, each variable values contains more than 1000 observations. 

Thank you. 

Reeza
Super User

1. Post the log that shows the error.

2. Post the results from the following code:

proc freq data=stdff;

table income_dx/missing;

run;

Also, Do you really need 3 nested loops? For example in the j=1 to 4 loop you don't end up using anywhere except the first line...

Lulus
Obsidian | Level 7

Thank you for help.  In the very beginning, the read bold lines are from log file.

and I've done the proc freq as mentioned.  There are values in every category of the income level. 

Not sure what means the j=1 to 4.  Actually I am very new to Array, could you explain more or you know any thing like step-debug I can do with SAS so I can better understand how the iteration goes.  Just wanted to do something to give dummy variables for

all of the variables.  (income, sex, sportsgroup....)

TimArm
Obsidian | Level 7

What you need to check is: are any of the values of income_dx outside the size of the array i.e. <1 or >7 ?

Lulus
Obsidian | Level 7

In my income_dx, the values are 1,2,3,4,5,6, and 9

TimArm
Obsidian | Level 7

9 is bigger than the size of your array!

Instead of array coding4 {*} salary1-salary6 salary7;

try array coding4 {10} salary1-salary6 salary7;

TimArm
Obsidian | Level 7

Then you also need do k=1 to 10; as well!

Lulus
Obsidian | Level 7

why you said that the k is irrelevant at this point?  Why did you mean by "outside of the do loop? "

TimArm
Obsidian | Level 7

What I meant was (although I failed to make it clear) was that you needed to know what the value of income_dx was at the point of the error. So, as Astounding says, the log may tell you.

If you do not have the log, then follow Reeza's advice and do a proc freq.

Astounding
PROC Star

Lulus,

SAS has already given you the detailed information you need.  Following the error message, SAS spits out the value of all your variables for that observation, including INCOME_DX.  We don't need a list of all the theoretically possible values for INCOME_DX, we need to know the value that INCOME_DX took for that particular observation where the ERROR occurred.  That information is already in your log.

Good luck.

Cynthia_sas
SAS Super FREQ

Hi:

  But the error message is complaining about an array subscript. And another clue is the warning that character variables are being converted to numeric. So, I would recommend that you look at all your index variables, in particular, INCOME_DX -- is it character or numeric? While you're at it, I'd also check GNDR_DX and ETHG_DX. Is it possible that INCOME_DX (or any of the other DX vars) is getting converted to missing or to a number greater than 7 (or greater than the limit of the array)???? I'd recommend running a PROC CONTENTS on your input SET to see whether INCOME_DX is character or numeric. If it is CHARACTER, then make sure that it will ALWAYS convert to a number and not missing. If it is NUMERIC, then make sure that the values are ONLY between 1 and 7 (you can check this with PROC FREQ).

  Also, just as a housekeeping note, ARRAY statements are compile time statements. That means they are only "touched" one time -- at compile time. You have them placed inside each DO loop -- that doesn't need to be the way you code ARRAY statements. You could have them all in one place under the SET statement. It would make your DO loops easier to read.  I wonder about the structure of your input data, that you have so many variable values being assigned inside nested DO loops, but you know your data and know whether you need to nest the loops like this.  For example, coding2(ETHG_dx)=1; is OUTSIDE of any DO loop, so it will happen 1 time. On the other hand, coding3(gndr_dx)=1; is INSIDE the DO loop for I, so it will get executed 6 times. If you only have 1 value for GNDR_DX, then you are executing this statement 5 extra times.

  Another thing I can think of is that your INCOME_DX variable is a character string that is either a salary variable with puntuation ($35,000) or a description of the salary (Over $30K) and neither of those values can be used as array subscripts. When SAS would try to convert these values from character to numeric, you would get a missing value, which would be an invalid array subscript.  INCOME_DX has to be a number between 1 and 7; GNDR_DX has to be a number between 1 and 4; and ETHG_DX has to be a number between 1 and 6.

 

cynthia

 

An alternative program with some comments to show the nesting.

  

data XXX;

set stdff;

  array coding2 {*} agroup_1-agroup_6;

  array coding3 {*} boys girls notdisclose nodata;

  array coding4 {*} salary1-salary6 salary7;

  ** initialize arrays to 0 and set values;

  do i=1 to 6;

     coding2(i)=0;

 

     do j=1 to 4;

        coding3(j)=0;

 

        do k=1 to 7;

           coding4(k)=0;

        end;  /* end for do k */

        coding4(income_dx)=1;  /* income_dx cannot exceed 7 */

   

     end;  /* end for do j */

 

     coding3(gndr_dx)=1;  /* gndr_dx cannot exceed 4 */

  

  end;   /* end for do i */

  

  coding2(ETHG_dx)=1;  /* ETHG_dx cannot exceed 2 */

drop i j k;

run;

Lulus
Obsidian | Level 7

it is Char, I used proc contents to check about it.  Thank you.

Cynthia_sas
SAS Super FREQ

Hi:

  A simple number without punctuation should convert correctly. The problem that I see, is when you say that INCOME_DX can possibly have a value of 9, but you have defined your CODING4 array to only have 7 elements, so a value for 9 will be considered "out of range".

cynthia

sas-innovate-2024.png

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.

 

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
  • 21 replies
  • 10083 views
  • 7 likes
  • 5 in conversation