Hi SAS community
I have heatmap of values (0-1). I have on a BY variable ("disease"). I want to do and I can't work out how:
Any help would be appreciate
proc template;
define statgraph corrHeatmap;
dynamic _Title;
begingraph;
entrytitle _Title;
rangeattrmap name='map';
endrangeattrmap;
rangeattrvar var=r attrvar=r attrmap='map';
layout overlay /
xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
heatmapparm x = x y = y colorresponse = rsquare /
xbinaxis=true ybinaxis=true
name = "heatmap" display=all colormodel=(white black);
continuouslegend "heatmap" /
orient = vertical location = outside title="Pearson Correlation";
endlayout;
endgraph;
end;
run;
proc sort data=fit;
by disease;
run;
proc sgrender data=fit template=corrHeatmap;
by disease;
dynamic _title="Correlation matrix";
run;
Using the RANGEATTRMAP is the best approach, but you're code needs a little adjustment:
1. The COLORMODEL option needed to be removed from the HEATMAPPARM statement. Instead, the RANGECOLORMODEL needs to be defined on the RANGE statement. Otherwise, there is no binding between the 0-1 range and the white-black color range
2. The RANGEATTRVAR needs to have the RSQUARE variable specified on the VAR option. This option points to the real column in the data. The ATTRVAR option specifies a new reference variable name. This variable (not the RSQUARE) should be used for the COLORRESPONSE on the HEATMAPPARM to create the correct binding.
3. The fake data is not required, so I removed it.
proc template;
define statgraph corrHeatmap;
dynamic _Title;
begingraph;
entrytitle _Title;
rangeattrmap name='map';
range 0.0-1.0 / rangecolormodel=(white black);
endrangeattrmap;
rangeattrvar var=rsquare attrvar=r attrmap="map";
layout overlay /
xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
heatmapparm x = x y = y colorresponse = r /
xbinaxis=true ybinaxis=true
name = "heatmap" display=all ;
continuouslegend "heatmap" /
orient = vertical location = outside title="Pearson Correlation"
VALUECOUNTHINT=11;
endlayout;
endgraph;
end;
run;
/* make some example data */
data fit;
do disease = 1 to 2;
do x = 0 to 3;
do y = 0 to 3;
rsquare = (disease + x**2 + y**2) / 25; /* make range in [0, 1] */
output;
end;
end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;
proc sort data=fit;
by disease;
run;
proc sgrender data=fit template=corrHeatmap;
by disease;
dynamic _title="Correlation matrix";
run;
Two suggestions:
1. Use the RANGE statement inside the RANGEATTRMAP/ENDRANGEATTRMAP block.
2. Add some fake data to each BY group to force the continuous legend to always display tick marks at 0 and 1. There might be a better way to do this. Maybe @DanH_sas knows a better way:
proc template;
define statgraph corrHeatmap;
dynamic _Title;
begingraph;
entrytitle _Title;
rangeattrmap name='map';
range 0-1; /* set range to [0,1] */
endrangeattrmap;
rangeattrvar var=r attrvar=r attrmap='map';
layout overlay /
xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
heatmapparm x = x y = y colorresponse = rsquare /
xbinaxis=true ybinaxis=true
name = "heatmap" display=all colormodel=(white black);
continuouslegend "heatmap" /
orient = vertical location = outside title="Pearson Correlation"
VALUECOUNTHINT=11;
endlayout;
endgraph;
end;
run;
/* make some example data */
data fit;
do disease = 1 to 2;
do x = 0 to 3;
do y = 0 to 3;
rsquare = (disease + x**2 + y**2) / 25; /* make range in [0, 1] */
output;
end;
end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;
proc sort data=fit;
by disease;
run;
/* HACK: insert fake data for rsquare=0 and rsquare=1 to fool the continuous axis legend */
data Fake;
do disease = 1 to 2; /* need fake obs for each value of disease */
rsquare = -1E-3; output;
rsquare = 1+ 1E-3; output;
end;
run;
data NewFit;
set Fake Fit;
by disease;
run;
proc sgrender data=NewFit template=corrHeatmap;
by disease;
dynamic _title="Correlation matrix";
run;
Using the RANGEATTRMAP is the best approach, but you're code needs a little adjustment:
1. The COLORMODEL option needed to be removed from the HEATMAPPARM statement. Instead, the RANGECOLORMODEL needs to be defined on the RANGE statement. Otherwise, there is no binding between the 0-1 range and the white-black color range
2. The RANGEATTRVAR needs to have the RSQUARE variable specified on the VAR option. This option points to the real column in the data. The ATTRVAR option specifies a new reference variable name. This variable (not the RSQUARE) should be used for the COLORRESPONSE on the HEATMAPPARM to create the correct binding.
3. The fake data is not required, so I removed it.
proc template;
define statgraph corrHeatmap;
dynamic _Title;
begingraph;
entrytitle _Title;
rangeattrmap name='map';
range 0.0-1.0 / rangecolormodel=(white black);
endrangeattrmap;
rangeattrvar var=rsquare attrvar=r attrmap="map";
layout overlay /
xaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'))
yaxisopts=(display=(line ticks tickvalues label) label=('Weeks wear'));
heatmapparm x = x y = y colorresponse = r /
xbinaxis=true ybinaxis=true
name = "heatmap" display=all ;
continuouslegend "heatmap" /
orient = vertical location = outside title="Pearson Correlation"
VALUECOUNTHINT=11;
endlayout;
endgraph;
end;
run;
/* make some example data */
data fit;
do disease = 1 to 2;
do x = 0 to 3;
do y = 0 to 3;
rsquare = (disease + x**2 + y**2) / 25; /* make range in [0, 1] */
output;
end;
end;
end;
/* check that rsquare is in [0,1] */
proc means data=fit;
class disease;
var rsquare;
run;
proc sort data=fit;
by disease;
run;
proc sgrender data=fit template=corrHeatmap;
by disease;
dynamic _title="Correlation matrix";
run;
Thank you Rick and Dan
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.