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

hello,

 

I have a dataset that contains an age (40-105)  variable and another f2-f49 variables  representing values for each age .

 

sample:

 

agef2f3f4f5f6
4011155914
41158515612
422575105
43316667132
4455181232812
4511841217

1

 

i would like to create 2 DIMENSION array - val -  that will contain the values in file.

so that later in the program, i will be able to refer to a spesifc age and f and get the value.

like :

val (40,3) = 15

val (44,5) = 28

 

 thanks for answering

 

miri.

 

 

      
      
      
      
      
      
      

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
KachiM
Rhodochrosite | Level 12

@mirib 

 

You would have received my reply now.

 

After posting it, I realized that the code is not generalized. It will work if you arrange the columns as

 

array f f&start_col - f&end_col;

where &start_col has to be always 2 and &end_col has to be 6. What if you want:

input age  f4 - f8;

instead of 

input age  f2 f3 f4 f5 f6;

A small correction to the previous code is made which takes care of any starting and ending column names ( they have to be contiguous in between):

 


data have;
infile cards expandtabs truncover;
input age  f4 - f8;
cards;
40 11 15 5  9  14
41 15 8  51 56 12
42 25 7  5  10 5
43 3  16 66 71 32
44 55 181   23 28 12
45 1  184   12 17 1
;
run;

%let start_row = 40;
%let end_row = 45;
%let start_col = 4;
%let end_col = 8;
data _null_;
   /** Load the 2-dimensional  Array **/
   if _n_ = 1 then do until(eof);
      set have end = eof;
      array ind[&start_row:&end_row, &start_col:&end_col] _temporary_;
      array f[&start_col:&end_col] f&start_col - f&end_col;
      row = age;
      do i = &start_col to &end_col;
         col = input(compress(vname(f[i]),,'kd'),8.);
         ind[row,col] = f[i];
         *put row = col = ind[row, col] =;
      end;
   end;
   /** Lookup the Array **/
   do age = 42, 40;
      do i = 5, 4, 6;
         put ind[age, i] =;
      end;
      put '==================================';
   end;
stop;
run;

 

 

View solution in original post

4 REPLIES 4
Ksharp
Super User

It is what IML is supposed to do. You need SAS/IML .

If you have any MATRIX problem . post it at IML forum. Rick is there.

 

data have;
infile cards expandtabs truncover;
input age	f2	f3	f4	f5	f6 ;
cards;
40	11	15	5	9	14
41	15	8	51	56	12
42	25	7	5	10	5
43	3	16	66	71	32
44	55	181	23	28	12
45	1	184	12	17	1
;

proc iml;
use have;
read all var{age};
read all var{f2	f3	f4	f5	f6} into val[c=col];
close;
row='age'+strip(char(age));
mattrib val r=row c=col;

temp=val['age40','f3'];
print temp;	

temp=val['age44','f5'];
print temp;

quit;

 

 

KachiM
Rhodochrosite | Level 12

EDITED: THIS HAS BEEN REVISED FOR GENERAL PURPOSE. SEE THE NEXT POST OF MINE

 

 

You want to lookup an array giving its row and column to get its content. It can be done via Hash objects and arrays. Arrays are preferable because it is faster and takes less memory. I am using a temporary 2-dimensional array for not crowding the PDV, Also, I am using macro variables to make the array dynamic.

 


%let start_row = 40;
%let end_row = 45;
%let start_col = 2;
%let end_col = 6;
data _null_;
   /** Load the 2-dimensional  Array **/
   if _n_ = 1 then do until(eof);
      set have end = eof;
      array ind[&start_row:&end_row, &start_col:&end_col] _temporary_;
      array f f&start_col - f&end_col;
      row = age;
      do i = &start_col to &end_col;
         col = input(compress(vname(f[i-1]),,'kd'),8.);
         ind[row,col] = f[i-1];
         *put row = col = ind[row, col] =;
      end;
   end;
   /** Lookup the Array **/
   do age = 42, 40, 45;
      do i = 5, 2, 6, 3;
         put ind[age, i] =;
      end;
      put '==================================';
   end;
stop;
run;

 

 

 

KachiM
Rhodochrosite | Level 12

@mirib 

 

You would have received my reply now.

 

After posting it, I realized that the code is not generalized. It will work if you arrange the columns as

 

array f f&start_col - f&end_col;

where &start_col has to be always 2 and &end_col has to be 6. What if you want:

input age  f4 - f8;

instead of 

input age  f2 f3 f4 f5 f6;

A small correction to the previous code is made which takes care of any starting and ending column names ( they have to be contiguous in between):

 


data have;
infile cards expandtabs truncover;
input age  f4 - f8;
cards;
40 11 15 5  9  14
41 15 8  51 56 12
42 25 7  5  10 5
43 3  16 66 71 32
44 55 181   23 28 12
45 1  184   12 17 1
;
run;

%let start_row = 40;
%let end_row = 45;
%let start_col = 4;
%let end_col = 8;
data _null_;
   /** Load the 2-dimensional  Array **/
   if _n_ = 1 then do until(eof);
      set have end = eof;
      array ind[&start_row:&end_row, &start_col:&end_col] _temporary_;
      array f[&start_col:&end_col] f&start_col - f&end_col;
      row = age;
      do i = &start_col to &end_col;
         col = input(compress(vname(f[i]),,'kd'),8.);
         ind[row,col] = f[i];
         *put row = col = ind[row, col] =;
      end;
   end;
   /** Lookup the Array **/
   do age = 42, 40;
      do i = 5, 4, 6;
         put ind[age, i] =;
      end;
      put '==================================';
   end;
stop;
run;

 

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

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