When you use an array in a SAS data step, sometimes you need to reinitialize the array elements to some value. For example zero or one. Not long ago, I learned a nifty little trick that allows you to do so easily. This post demonstrates four different methods to set all array elements to some specified value. I will show an example for both regular and temporary arrays. One smarter than the other.
Go Through the SAS Array Indexes
The obvious approach is to simply go through each of the SAS array elements and set that element to zero. Below, I do so in a simple do loop. First, I create a matrix x with ten elements. Next, I simply loop through each element and set it to zero. You can check the log and verify that all elements are zero.
data _null_; array x (1 . 3 . 5 . 7 . 9 .); do i=1 to dim(x); x[i]=0; end; put x[*]; run;
Next, let us take things a bit further. Instead of looping through each element, I use the Call Stdize Routine to handle all entries at once. First, I create the same array as above. Some elements are missing, some are not. Next, I use Call Stdize. I use the Replace Option to make sure that missing values are set to zero. Then I use the Mult= Option to multiply non missing values by the third argument 0.
Finally, I have to supply a list of variables to the routine. I feed it the x[*], which means every element of x. However, the SAS routine requires there to be at least one non missing variable value. Therefore, I also list _N_ as an input variable to overcome this. I can safely do so, because _N_ is always a positive integer.
data _null_; array x (1 . 3 . 5 . 7 . 9 .); call stdize('replace','mult=',0,of x[*],_N_); put x[*]; run;
The SAS Call Stdize Documentation says that the routine “Standardizes the values of one or more variables”. Now, as you may know, temporary arrays are not made of actual variables as a regular array. Consequently, the above trick does not work for temporary arrays. Instead, we have to complicate things a little. Below, I create a subroutine in PROC FCMP named Fillarray. I do this by compiling the Fillmatrix Routine. Next, I create the same array as before, but declare it as temporary. This means that SAS does not create variables for each entry in the PDV. Now, I can use the Fillarray Routine to set all the entrances in the temporary array x to zero. Or any other constant value for that matter.
proc fcmp outlib=work.functions.fun; subroutine fillarray (x[*], value); outargs x; call fillmatrix (x, value); endsub; quit; option cmplib=work.functions; data _null_; array x _temporary_ (1 . 3 . 5 . 7 . 9 .); call fillarray (x, 0); temp=catq('d', ' ', of x[*]); put temp=; run;
As a final example, PROC FCMP also has a subroutine designed for this very purpose. While the Call Fillmatrix above can set the array elements to any constant value, the Call Zeromatrix Routine sets all the elements to just zero. See a small example below.
proc fcmp outlib=work.functions.fun; subroutine arraytozero (x[*]); outargs x; call zeromatrix (x); endsub; quit; option cmplib=work.functions; data _null_; array x _temporary_ (1 . 3 . 5 . 7 . 9 .); call arraytozero (x); temp=catq('d', ' ', of x[*]); put temp=; run;
In this post, I demonstrate four approaches to setting all array elements to zero. I show techniques for both regular and temporary arrays. It is more complicated to do so with a temporary array. However, all it takes is to compile a routine through the FCMP procedure.
I learned this trick from the users FreelanceReinhard and hashman at the SAS Online Community. For other posts related to SAS arrays check out SAS Array Lookup Example, Use Temporary Arrays to Store Lagged Values in SAS and 4 Techniques To Sort An Array in SAS.
You can download the entire code from this post here.