You can perform BY-group processing in PROC IML by making use of the UNIQUEBY function and a DO loop.
The UNIQUEBY function returns the locations of the unique BY-group combinations for a sorted or indexed matrix. If the matrix is not sorted then use the SORT function prior to the UNIQUEBY function. With the vector that it returns, you can use the subscript operator, [ ], to perform operations on each of the unique BY groups.
The example below shows how this can be done. The POTTERY data set has four BY groups defined by the variable SITE.
data pottery;
input Site X Fe Mg Ca Na;
datalines;
1 14.4 7.00 4.30 0.15 0.51
1 13.8 7.08 3.43 0.12 0.17
1 14.6 7.09 3.88 0.13 0.20
1 11.5 6.37 5.64 0.16 0.14
1 13.8 7.06 5.34 0.20 0.20
1 10.9 6.26 3.47 0.17 0.22
1 10.1 4.26 4.26 0.20 0.18
1 11.6 5.78 5.91 0.18 0.16
1 11.1 5.49 4.52 0.29 0.30
1 13.4 6.92 7.23 0.28 0.20
1 12.4 6.13 5.69 0.22 0.54
1 13.1 6.64 5.51 0.31 0.24
1 12.7 6.69 4.45 0.20 0.22
1 12.5 6.44 3.94 0.22 0.23
2 11.8 5.44 3.94 0.30 0.04
2 11.6 5.39 3.77 0.29 0.06
3 18.3 1.28 0.67 0.03 0.03
3 15.8 2.39 0.63 0.01 0.04
3 18.0 1.50 0.67 0.01 0.06
3 18.0 1.88 0.68 0.01 0.04
3 20.8 1.51 0.72 0.07 0.10
4 17.7 1.12 0.56 0.06 0.06
4 18.3 1.14 0.67 0.06 0.05
4 16.7 0.92 0.53 0.01 0.05
4 14.8 2.74 0.67 0.03 0.05
4 19.1 1.64 0.60 0.10 0.03
;
This PROC MEANS step uses BY-group processing to compute the sums of variables X and FE.
proc means sum;
by site;
var x fe;
run;
|
The MEANS Procedure
|
The following IML code reproduces the results of the preceding PROC MEANS step using the UNIQUEBY function to perform BY-group processing. These statements invoke PROC IML and read the SITE, X, and FE variables from the POTTERY data set into a matrix named A:
proc iml;
use pottery;
read all var{site x fe} into a;
In these statements you should not need to change anything other than the matrix name.
unique_rows=uniqueby(a,1,1:nrow(a));
do i=1 to nrow(unique_rows);
/* Next line is for the last BY group */
if i=nrow(unique_rows) then index=unique_rows[i]:nrow(a);
else index=unique_rows[i]:unique_rows[i+1]-1;
submat=a[index,];
Below is where you put your function. This particular example computes the sum for X and FE in each BY group.
sum=sum//submat[+,2:3];
end;
print sum;
quit;
| ||||||||||