I am assuming that the data are sorted by the ID variable and that the order of the observations in the MyData set match the order of the variables and observations in the Supplement matrix. The main techniques you need to read about and learn are
1. The LOC-ELEMENT technique to find the variables that are in each ID group.
2. Use the ALLCOMB function to generate all pairwise combinations of the variables
3. Convert subscripts [i,j] into an index
4. The UNIQUEBY-LOC technique to loop over the values of the ID variable
Hopefully the comments in the program will adequately describe each step.
DATA mydata ;
INPUT ID
Country $
value ;
CARDS ;
1 CH 24
1 ES 55
1 EE 20
2 BR 10
2 CO 50
2 CH 10
3 CH 24
3 BR 10
3 ES 55
3 CO 50
;
data supplement;
input Country $ CH DE BR ES CU CO EE;
cards;
CH 1 0.1 0.2 0.4 0.5 0.6 0.7
DE 0.1 1 0.5 0.6 0.7 0.8 0.9
BR 0.2 0.5 1 0.1 0.2 0.3 0.4
ES 0.4 0.6 0.1 1 0.4 0.5 0.6
CU 0.5 0.7 0.2 0.4 1 0.7 0.8
CO 0.6 0.8 0.3 0.5 0.7 1 0.9
EE 0.7 0.9 0.4 0.6 0.8 0.9 1
;
/* assume MyData is sorted by ID and that the countries for
each ID are the same order as in the Supplement matrix
*/
proc iml;
use mydata;
read all var {ID 'Country' 'Value'};
close;
use supplement;
read all var _NUM_ into R[colname=varNames];
close;
/***************************************************/
/* Demonstrate the computation for ID=1 */
idx = loc(ID=1);
c = Country[idx]; /* countries for ID=1 */
v = Value[idx]; /* values for ID=1 */
print c v;
/* which variables are being asked for?
LOC-ELEMENT technique:
https://blogs.sas.com/content/iml/2015/05/11/loc-element-trick.html
*/
varIdx = loc( element(varNames, c) );
print varIdx;
/* get all pairwise combinations:
https://blogs.sas.com/content/iml/2013/09/30/generate-combinations-in-sas.html
*/
pairs = allcomb(ncol(varIdx), 2);
varPairs = shape( varIdx[pairs], 0, 2);
print pairs varPairs;
/* convert subscripts to indices:
https://blogs.sas.com/content/iml/2011/02/16/converting-matrix-subscripts-to-indices.html
*/
ndx = sub2ndx(dimension(R), varPairs);
w = R[ndx];
x = v[pairs[,1]];
y = v[pairs[,2]];
print w x y;
wsum = sum( w # x # y );
print wsum;
/*****************************************************/
/***************************************************/
/* Now the real thing: compute for all IDs. Assume sorted by ID */
/***************************************************/
/* For UNIQUEBY-LOC trick, see
https://blogs.sas.com/content/iml/2011/11/07/an-efficient-alternative-to-the-unique-loc-technique.html
*/
b = uniqueby(ID); /* b[i] = beginning of i_th category */
labl = char(ID[b]);
wsum = j(nrow(b),1); /* 3. Allocate vector to hold results */
b = b // (nrow(ID)+1); /* trick: append (n+1) to end of b */
do i = 1 to nrow(b)-1; /* 4. For each level... */
idx = b[i]:(b[i+1]-1); /* 5. Find observations in level */
/* 6. Compute statistic on those values */
c = Country[idx]; /* countries for ID=1 */
v = Value[idx]; /* values for ID=1 */
varIdx = loc( element(varNames, c) );
pairs = allcomb(ncol(varIdx), 2);
varPairs = shape( varIdx[pairs], 0, 2);
ndx = sub2ndx(dimension(R), varPairs);
w = R[ndx];
x = v[pairs[,1]];
y = v[pairs[,2]];
wsum[i] = sum( w # x # y );
end;
print wsum[rowname=labl];
... View more