0
votes

I would like some help with SAS Arrays and do loops

I have some code which nearly works and would like an explanation why it doesn't work as expected. If I can understand why it doesn't work then that will help with part B which doesn't work at all. Part A) I have four variables ILC_Financial_products_owned__ var81 var82 var83 which can take any of the values 01 to 14 (note they are character, this will be important later). I wish to create 14 new variables fin_own01 to fin-own14 that are either 1 or missing if the any of the first four variables contain that value. e.g if ILC_Financial_products_owned__ = '01' then fin_own01 =1.

data a;
set b;
fin_own{14} ;
do j    = '01','02','03','04','05','06','07',
'08','09','10','11','12','13','14';
if ILC_Financial_products_owned__  = j 
or var81 = j or var82 = j or var83 = j          
then fin_own{j}     = 1;
run;

This creates variables fin_own1, fin_own2 etc. I would like to know why it doesn't create variables called fin_own01, fin_own02. Other than that it works

Part B) now it gets harder instead of the values '01' to '14' I have another 4 variables that can be any of '01','06','71','A2' ( I've shortened the list 40 below). The values are not consectutive and because the of the character values I can't solve the problem as in Part A). The problem is now if I try similar code I get the

error message Array subscript out of range when I try to assign the new value leisure_reg{k} = 1;

data a;
set b;
array leisure_reg{40} ;
do k = '01','06','08','11','13','14','15','16','17','20','21','24','26','27','29','30','32','33','35','36'
  ,'38','41','42','48','50','51','52','53','58','60','64','68','70','71','72','73','94','95','A2','A4';
if ilc_regular_leisure_interestsac  = k or var100 = k or var101 = k or var102 = k or var103 = k then leisure_reg{k} = 1;

I would appreciate some help to know if I need to use a macro to do this or something else?

2
In your first code block you don't have the word array in your array declaration? - Reeza

2 Answers

0
votes

Regarding Part A, when you define an array without explicitly naming the variables, SAS will default to a numbered range, from 1 to n - in this case 14.

The below would achieve your desired result :

array fin_own{14} fin_own01 fin_own02 /* etc */ fin_own13 fin_own14 ;

You can address your issues in Part B by using an array of your lookup values.

A simplified example :

array kvalues{5} $2. ('01', '03', '05', 'A3', 'B7') ;
array leisure_reg{5} ;
do k = 1 to dim(kvalues) ;
  v = kvalues{k} ;
  leisure_reg{k} = (ilc_regular_leisure_interestsac = v or var100 = v or var101 = v or var102 = v or var103 = v) ;
end ;

If you require the leisure_reg variables to be named based on the k-value rather than the array index, you'll have to create a new field and transpose it afterwards :

 
array kvalues{5} $2. ('01', '03', '05', 'A3', 'B7') ;
array leisure_reg{5} ;
do k = 1 to dim(kvalues) ;
  v = kvalues{k} ;
  leisure_reg{k} = (ilc_regular_leisure_interestsac = v or var100 = v or var101 = v or var102 = v or var103 = v) ;
  kvar = cats('leisure_reg',v) ;
  kval = leisure_reg{k} ;
  output ;
end ;

/* proc transpose on with kvar as ID, kval as var */
0
votes

Answer to part A. Define two arrays, one for new and one for old variables. Since the index is from 1 to 14 convert it to a number and use that in your array index.

Array fin_own(14) fin_own01 - fin_own14 (14*0);
Array old_val(4) var81 var84;

Do I=1 to 4;
    Index=input(old_val, 8.);
     Fin_own(index) = 1;
 End;