DATA Step, Macro, Functions and more

Array {I,J}

Accepted Solution Solved
Reply
Contributor
Posts: 33
Accepted Solution

Array {I,J}

hello there,

 

I have a question on arrays.

so if there is a case that a two demensional array should be used in a dataset, is there a possibility to do so.

 

for instance. this way is valid             array myarray{*} _numeric_;

                                                          

                                                     set work.mydataset;

                                                          array yourarray{i,j} _numeric_;

                                                          do i = 1 to dim(yourarray);

                                                               do j =1 to dim(yourarray);

                                                                        ...........sas code.....................

                                                               end;

                                                           end;

 

                                               etc.......

 

 

 

thanks in advance. Smiley Happy


Accepted Solutions
Solution
‎07-07-2017 08:39 AM
PROC Star
Posts: 7,363

Re: Array {I,J}

Just for fun/learning, here is an example of doing what you asked.

 

data have;
  input a b c d e f;
  cards;
10 11 12 13 14 15
1 2 3 4 5 6
2 4 . 8 . 12
;

 

data want;
  set have;
  array test(2,3) _numeric_;
  do i=1 to 2;
    if i eq 1 then x=sum(test(i,1),test(i,2),test(i,3));
    else y=sum(test(i,1),test(i,2),test(i,3));
  end;
run;

 

HTH,

Art, CEO, AnalystFinder.com

 

View solution in original post


All Replies
Super Contributor
Posts: 251

Re: Array {I,J}

No, it doesn't work like that. SAS's definition of arrays is unlike most (all?) other languages. All it does is set a template over a collection of variables: there is no space allocated as such by the array statement (I will defend this against all comers!).

 

So when you define an array, you have to set the bounds of the array dimensions. When you use the _numeric_ or _char_ special variable names, you're assigning the array in only one dimension. WIthin the brackets you can set either the numeric bounds or, as you've done in your first example "*", to let the SAS parser pick up the bounds from metadata.

 

So your second example won't work for two reasons:

  • the array bounds must be numeric constants (not variables) or *.
    • Even having variables i and j in work.dataset (and having variables called that in a dataset is never a good idea!) won't work, because they're not constants.
  • _numeric_ is inherently one-dimensional. It is possible to treat it as multi-dimensional, but doing that would be fraught with difficulty; I would never recommend it because you have very little control over the order in which your variables are referenced.

 

PROC Star
Posts: 7,363

Re: Array {I,J}

@LaurieF: If NO space is allocated for SAS arrays, then please explain how the following works:

 

%let n = 10 ;
data _null_ ;
   array work w1-w&n (&n * .M);
   put work[*] ;
   length _init_ $ %eval(8 * &n) ;
   _init_ = repeat (put (1, rb8.), &n - 1) ;
   _addw_ = addrlong (work[1]) ;
   call pokelong (_init_, _addw_, %eval(8 * &n)) ;
   put work[*] ;
run ;

 

Super Contributor
Posts: 251

Re: Array {I,J}

Oh - that's a little harsh!

 

OK here goes: it's not defining variables in itself. This is standard SAS datastep operating procedure: in any statement, like retainlength or format isn't actively defining a variable. The SAS parser goes off, creates the variable where it doesn't already exist and allows the (in this case) non-executable statement to do its thing. array doesn't do anything differently to any other statement.

 

The only time, as far as I'm concerned, that array defines variables is with the _temporary_ keyword, and even then it's still just putting a template over a piece of (possibly discontiguous) storage.

PROC Star
Posts: 7,363

Re: Array {I,J}

I didn't mean for it to be harsh .. just an example that (I think) contradicts your statement. And I think the array statement, in this case, creates new storage areas that are, in fact, contiguous. Paul Dorfman is much more knowledgeable with the particulars than I am. In case you're interested, he describes it in the post/thread at:

https://listserv.uga.edu/cgi-bin/wa?A2=ind1701b&L=SAS-L&O=D&F=P&X=4D432A58082FCD2383&P=59414

 

Art, CEO, AnalystFinder

PROC Star
Posts: 7,363

Re: Array {I,J}

SAS can definitely have multidimensional arrays, but not the way you've stated in your code. You'd have to give an example of what you're trying to do.

 

Art, CEO, AnalystFinder.com

 

Super User
Posts: 10,516

Re: Array {I,J}

You need to declare the number of elements in a multiple dimenstion array with integers. You can't use datastep variables to do so:

 

array myarray ( 10,5) ; not array myarray(i,j); This will generate ERROR 22-322: Expecting an integer constant.

 

If your declared size does not exactly meet the number of _numeric_ variables you will get an error; either "Too few variables defined for the dimension" meaning that there are not enough existing numeric variables to fill the array or "Too many variables defined for the the dimension" meaning you did not allocate enough space for all of the _numeric_ variables.

 

You can use

Array myarray _numeric_;

without problems. Use of indices to treat as a multidimensional array will be up to you to ensure that the row and column variables are as you think they are.

Solution
‎07-07-2017 08:39 AM
PROC Star
Posts: 7,363

Re: Array {I,J}

Just for fun/learning, here is an example of doing what you asked.

 

data have;
  input a b c d e f;
  cards;
10 11 12 13 14 15
1 2 3 4 5 6
2 4 . 8 . 12
;

 

data want;
  set have;
  array test(2,3) _numeric_;
  do i=1 to 2;
    if i eq 1 then x=sum(test(i,1),test(i,2),test(i,3));
    else y=sum(test(i,1),test(i,2),test(i,3));
  end;
run;

 

HTH,

Art, CEO, AnalystFinder.com

 

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 7 replies
  • 174 views
  • 6 likes
  • 4 in conversation