BookmarkSubscribeRSS Feed
sfridy
Fluorite | Level 6

Is there a way to create an array as a data structure in SAS? I'm trying to nest an if statement within various Do loops in order to get around having to code a very large number of if/else statements. I was thinking something like the attached code. However I've learned that SAS arrays are arrays of variables so this wouldn't work.

data temp;
	set TRNSSPLITCOLUMNS;

array hla{11}  HLA-A HLA-B HLA-C HLA-DPA1 HLA-DPB1 HLA-DQA1 HLA-DQB1 HLA-DRB1 HLA-DRB3 HLA-DRB4 HLA-DRB5;
array allele{11} A B C DPA1 DPB1 DQA1 DQB1 DRB1 DRB3 DRB4 DRB5;
array dors{2} DNA SER;
array locus{11} 1-11;
array antigen{2} 1 2;

DO i=1 to 2; /*For antigen 1 and 2*/
	DO j=1 to 2; /*For DNA and SER*/
		DO k=1 to 11; /*For each of the antigen loci variable*/
			DO l=1 to 11; /*For each HLA locus*/	

				If cat('Antigen',antigen{i},'_locus',locus{k}) = hla{l} and cat('Antigen',antigen{i},'_typ_meth',locus{k}) = dors{j} 
					then cat(allele{l}, '_',dors{j},'TYP',antigen{i}) = cat('Antigen',antigen{i},'_GenTyping',locus{k});

			end;
		end;
	end;
end;

run;
8 REPLIES 8
Reeza
Super User
array locus{11} _temporary_  (1:11);
sfridy
Fluorite | Level 6

Thank you! That seems to work, plus I realized that I don't actually need locus and antigen. Two things though:

 

-I get an error that there are 'Too many variables defined for the dimensions specified for my arrays. When I replace the dimension length with an * I get a warning of partial initiation. 

 

-It seems to think that the function cat() that I'm trying to call is an array that is undefined.

 

Thoughts?

 

Reeza
Super User

Your variable names have a hyphen (-), should that be an underscore instead?

Those are not valid SAS variable names so they are incorrect declarations. 

 

Run a PROC CONTENTS to see the variable names. If it happens to be the names you have to reference them as:

 

'Variable - Name'n

 

Which is why I hate that naming option. You can turn it off using 

 

Option validvarname=V7;

 

sfridy
Fluorite | Level 6

It complains about arrays with values that don't have hyphens as well, so it might be something else. I'm running it with partial initiation to see what happens.

Reeza
Super User

@sfridy wrote:

It complains about arrays with values that don't have hyphens as well, so it might be something else. I'm running it with partial initiation to see what happens.


That seems like a bad idea. Hyphens are used to list variables in an array definition which is also why it'll cause issues for you. Check your log. 

 

Temporary arrays can hold data and hash tables. Those are two approaches you can consider. Also, DS2 does have the concept of objects if you're more familiar with that style of programming. 

ballardw
Super User

Here is an example of using a temporary array of fixed values (a list if you will) to search for matches against an existing variable.

 

data junk;
   set sashelp.class;
   array mynames{5} $ 10 ('James','Henry','Fred','Jane','Mary');
   do i=1 to dim(mynames);
      if mynames[i]=name then output;
   end;
run;

With appropriate values and constructs your search should work though I think you want to use CATS instead of CAT.

 

 

However this snippet will fail as the function Cat (and cats, catx and such) are not allowed on the left side of an assignment statement.

If the target variable already exists in your input set then you would want to carefully create an array that you can use the values of the

index variables to address a multidimensional array. Maybe. If the variables do not exist then you could create them as part of an array statement.

then cat(allele{l}, '_',dors{j},'TYP',antigen{i}) = cat('Antigen',antigen{i},'_GenTyping',locus{k});

The above statement is going to generate errors about:

 

ERROR: Undeclared array referenced: cat.

because the function cat cannot be used as attempted.

 

Tom
Super User Tom
Super User

I cannot figure out what you are trying to do.

Please explain the problem you are trying to solve.  Sample input and output data would make the explanation clearer.

 

Note ARRAYs in a SAS datastep are not "data structures". They are a convenient way to reference a series of similar variables.

 

Tom
Super User Tom
Super User

I think you want to set initial values for your arrays.

405  data _null_;
406    array dors(2) $3 ('DNA' 'SER');
407    array locus(11) 8 (1:11);
408    put (dors(*) locus(*) ) (=/);
409  run;


dors1=DNA
dors2=SER
locus1=1
locus2=2
locus3=3
locus4=4
locus5=5
locus6=6
locus7=7
locus8=8
locus9=9
locus10=10
locus11=11

You could also use _TEMPORARY_ arrays if you did not want to create the actual variables.  This also has the advantage that the values are automatically retained.  

 

 

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!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 8 replies
  • 1644 views
  • 2 likes
  • 4 in conversation