Hello everyone,
is there a way to calculate both Spearman and Pearson correlation and combine them in one table?
In academic papers, I often see tables with e.g. Pearson correlation below the diagonal and Spearman above the diagonal.
Here is what I'm doing as of now, but I'm unsure how to put it together like described above:
Proc Corr data = have Pearson Spearman OUTP=P_test OUTS=S_test;
Var Var_1 Var_2 Var_3;
Run;
This of course gives me two tables - what I would like is just one table with both Spearman and Pearson.
Thanks in advance!
It is a SAS/IML thing. I think @Rick_SAS would like this kind of matrix very much.
data have;
set sashelp.class;
run;
proc iml;
use have;
read all var _num_ into x[c=vname];
close;
pearson=corr(x,'pearson');
pearson[loc(row(pearson)<col(pearson))]=0;
spearman=corr(x,'spearman');
spearman[loc(row(spearman)>col(spearman))]=0;
want=pearson+spearman-diag(pearson);
print want[c=vname r=vname l=''];
quit;
I am not sure what the word "combine" means to you.
What it means to me is something like this:
data want;
length type $ 8;
set p_test(in=in1) s_test(in=in2);
where _type_='CORR';
if in1 then type='Pearson';
if in2 then type='Spearman';
drop _type_ _name_;
run;
If you really need pearson above the diagonal and spearman below the diagonal, that could be done with the merge statement and arrays. But I would encourage you to not do that; the output from the code above is completely clear and useful, while the output of Pearson above the diagonal and Spearman below the diagonal leads to confusion as the viewer has to stop and think and remember which is above the diagonal and which is below, and potentially get it wrong.
It is a SAS/IML thing. I think @Rick_SAS would like this kind of matrix very much.
data have;
set sashelp.class;
run;
proc iml;
use have;
read all var _num_ into x[c=vname];
close;
pearson=corr(x,'pearson');
pearson[loc(row(pearson)<col(pearson))]=0;
spearman=corr(x,'spearman');
spearman[loc(row(spearman)>col(spearman))]=0;
want=pearson+spearman-diag(pearson);
print want[c=vname r=vname l=''];
quit;
I like KSharp's solution. It can be shortened by using a 0/1 mask to form the upper/lower parts of the matrix, rather than using indices:
data have;
set sashelp.class;
run;
proc iml;
use have;
read all var _num_ into x[c=vname];
close;
pearson=corr(x,'pearson');
spearman=corr(x,'spearman');
IsUpper = (row(pearson)>col(pearson));
want = IsUpper#Pearson + ^IsUpper#Spearman;
print want[c=vname r=vname l='Correlations: Lower=Pearson; Upper=Spearman'];
Thanks everyone!
Ksharp and Rick, your solutions worked for me - thanks to PaigeMiller for your input as well.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.