BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
drip_
Obsidian | Level 7

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!

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

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;

Ksharp_0-1663329334641.png

 

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
Ksharp
Super User

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;

Ksharp_0-1663329334641.png

 

Rick_SAS
SAS Super FREQ

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'];
drip_
Obsidian | Level 7

Thanks everyone!

Ksharp and Rick, your solutions worked for me - thanks to PaigeMiller for your input as well.

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
  • 4 replies
  • 1434 views
  • 4 likes
  • 4 in conversation