BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
hellohere
Pyrite | Level 9

Proc CORR creates m*m correlation matrix ... how to convert it into pair-wise dataset?!

Say here are ten variables, CORR creates 10*10 correlation matrix, need to convert into 10*10=100 row (var1 var2 corr12)..

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

See the article, "Use a bar chart to visualize pairwise correlations."

The focus of that article is to create a bar chart of the pairwise correlations, but you can use the same code to create a list.

The SAS/IML language has similarities with R, but if you are new to SAS, here is an explicit example, modified from the article:


ods exclude all;
proc corr data=sashelp.Heart;      /* pairwise correlation */
   var _NUMERIC_;
   ods output PearsonCorr = Corr;  /* write correlations, p-values, and sample sizes to data set */
run;
ods exclude none;

proc iml;
use Corr;
   read all var "Variable" into ColNames;  /* get names of variables */
   read all var (ColNames) into mCorr;     /* matrix of correlations */
close Corr;

numCols = ncol(mCorr);                /* number of variables */
numPairs = numCols*(numCols-1) / 2;
length = 2*nleng(ColNames) + 5;       /* max length of new ID variable */
PairNames = j(NumPairs, 1, BlankStr(length));
i = 1;
do row= 2 to numCols;                 /* construct the pairwise names */
   do col = 1 to row-1;
      PairNames[i] = strip(ColNames[col]) + " vs. " + strip(ColNames[row]);
      i = i + 1;
   end;
end;
 
lowerIdx = loc(row(mCorr) > col(mCorr));  /* indices of lower-triangular elements */
Corr = mCorr[ lowerIdx ];

create CorrPairs var {"PairNames" "Corr"};
append;
close;
QUIT;

proc print data=CorrPairs; run;

View solution in original post

7 REPLIES 7
Rick_SAS
SAS Super FREQ

See the article, "Use a bar chart to visualize pairwise correlations."

The focus of that article is to create a bar chart of the pairwise correlations, but you can use the same code to create a list.

The SAS/IML language has similarities with R, but if you are new to SAS, here is an explicit example, modified from the article:


ods exclude all;
proc corr data=sashelp.Heart;      /* pairwise correlation */
   var _NUMERIC_;
   ods output PearsonCorr = Corr;  /* write correlations, p-values, and sample sizes to data set */
run;
ods exclude none;

proc iml;
use Corr;
   read all var "Variable" into ColNames;  /* get names of variables */
   read all var (ColNames) into mCorr;     /* matrix of correlations */
close Corr;

numCols = ncol(mCorr);                /* number of variables */
numPairs = numCols*(numCols-1) / 2;
length = 2*nleng(ColNames) + 5;       /* max length of new ID variable */
PairNames = j(NumPairs, 1, BlankStr(length));
i = 1;
do row= 2 to numCols;                 /* construct the pairwise names */
   do col = 1 to row-1;
      PairNames[i] = strip(ColNames[col]) + " vs. " + strip(ColNames[row]);
      i = i + 1;
   end;
end;
 
lowerIdx = loc(row(mCorr) > col(mCorr));  /* indices of lower-triangular elements */
Corr = mCorr[ lowerIdx ];

create CorrPairs var {"PairNames" "Corr"};
append;
close;
QUIT;

proc print data=CorrPairs; run;
Tom
Super User Tom
Super User

Why not just use normal SAS code?
Generate the correlations.

Transpose.

proc corr data=sashelp.heart out=corr noprint;
 var _numeric_;
run;
proc transpose
  data=corr(rename=(_name_=LEFT))
  out=pairs(rename=(_name_=RIGHT) drop=_label_ )
;
  by left notsorted;
  where _type_='CORR';
  id _type_;
run;

Results:

Obs    LEFT          RIGHT            CORR

  1    AgeCHDdiag    AgeCHDdiag      1.00000
  2    AgeCHDdiag    AgeAtStart      0.55091
  3    AgeCHDdiag    Height         -0.21042
  4    AgeCHDdiag    Weight         -0.13741
  5    AgeCHDdiag    Diastolic      -0.03510
  6    AgeCHDdiag    Systolic        0.06924
  7    AgeCHDdiag    MRW             0.00642
  8    AgeCHDdiag    Smoking        -0.28357
  9    AgeCHDdiag    AgeAtDeath      0.74811
 10    AgeCHDdiag    Cholesterol     0.00363
 11    AgeAtStart    AgeCHDdiag      0.55091
 12    AgeAtStart    AgeAtStart      1.00000
 13    AgeAtStart    Height         -0.13173
 14    AgeAtStart    Weight          0.09352
 15    AgeAtStart    Diastolic       0.27540
 16    AgeAtStart    Systolic        0.37938
 17    AgeAtStart    MRW             0.20451
 18    AgeAtStart    Smoking        -0.16743
 19    AgeAtStart    AgeAtDeath      0.68860
 20    AgeAtStart    Cholesterol     0.27341
 21    Height        AgeCHDdiag     -0.21042
...

You could eliminate the self correlations and the duplicate entries by just filtering to the observations where LEFT < RIGHT.

hellohere
Pyrite | Level 9
Works great. Thanks.
Ksharp
Super User
data have;
 set sashelp.Heart;
run;

ods exclude all;
proc corr data=have;      /* pairwise correlation */
   var _NUMERIC_;
   ods output PearsonCorr = Corr;  /* write correlations, p-values, and sample sizes to data set */
run;
ods exclude none;

proc sort data=corr(drop=Label) out=corr2;
by variable;
run;

proc sql noprint;
select variable into : vname separated by ' ' from corr2;
quit;
proc transpose data=corr2 out=want;
by variable;
var &vname.;
run;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 1644 views
  • 4 likes
  • 5 in conversation