1. 什么是散点图(Scatter Plot)?
散点图是指在回归分析中,数据点在直角坐标系平面上的分布图。散点图表示因变量随自变量而变化的大致趋势,据此可以选择合适的函数对数据点进行拟合。
如何使用散点图呢?用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。散点图将序列显示为一组点,值由点在图表中的位置表示,类别由图表中的不同标记表示。
2. 临床试验中散点图举例
下图是一个项目中的散点图,图形中包含研究中两试验组的两指标基线变化值的散点图,以及各组数据的拟合回归直线。图标中的内容包含组别人数、Spearman相关系数以及对应的假设检验的P值。
3. SAS中运用GTL生成散点图
我将sashelp.class作为源数据,Sex作为试验分组,Height和Weight作为散点图的分析变量,运用GTL来实现上图的效果。
用GTL模板出图,首先要制作模板,先把模板框架写好,不断向框架中添加图形中需要的元素。
proc template;
define statgraph scatterplot;
begingraph;
···
···
endgraph;
end;
run;
先在模板中定义坐标轴的属性,考虑到坐标轴需要覆盖数据的所有范围,Y轴为Height,坐标轴范围设为50--80,间隔为5;X轴为Weight,坐标轴范围设置为40--150了,间隔为10。
layout overlay/
yaxisopts=(
label = "Height" labelattrs = (size = 7) tickvalueattrs=(size=7pt)
linearopts=(ViewMin=50 ViewMax=80 tickValueSequence=(start = 50 end = 80 increment = 5))
)
xaxisopts=(
label = "Weight" labelattrs = (size = 7) tickvalueattrs=(size=7pt)
linearopts=(ViewMin=40 ViewMax=150 tickValueSequence=(start = 40 end = 150 increment = 10))
);
···
···
endlayout;
坐标轴属性设置后,进行Scatterplot、Regressionplot图形的设置。试验分组为Sex,group=sex
。
layout overlay/
···
···
scatterplot y = height x = weight / group = sex name = "scatter";
regressionplot y = height x = weight / group = sex name = "fitline";
···
···
endlayout;
图形设置好后,添加图标(Legend)信息:
layout overlay/
···
···
discretelegen "scatter" / border=false;
···
···
endlayout;
调用已经设置好的模板来查看图形结果:
proc sgrender data=sashelp.class template=scatterplot;
run;
与前面的示例图相比,有一些需要地方需要改进:
- 例图中,试验分组的颜色分别是红色和绿色,目前出图的颜色不同;
- 例图中,散点图两组的标志为圆形和三角形,目前出图的标志都是圆形;
对于以上两点,如何使现在出的图与例图一致呢?通常,改变数据点的颜色和标志只要在散点图语句后面的添加具体选项就好,例如,markerattrs=(size=6pt color=red symbol=circle)
。但是,目前出图的选项是group=sex
,如果直接设置用markerattrs选项,会覆盖group选项的默认设置,使得两组的颜色与标志都相同。如何解决这个问题呢?通常有两种方法。
- 第一种方法,针对每一组的数据,单独生成Scatterplot和Regressionplot,每一个语句中单独设置数据指标的颜色和形状。这个方法需要重新处理数据,使得各组别的数据分开。
layout overlay/
···
···
scatterplot y = height_M x = weight_M / name = "scatter_M" markerattrs=(size=6pt color=red symbol=circle);
scatterplot y = height_F x = weight_F / name = "scatter_F" markerattrs=(size=6pt color=green symbol=triangle);
regressionplot y = height_M x = weight_M / name = "fitline_M" lineattrs=(color=red thickness=1px pattern=1);
regressionplot y = height_F x = weight_F / name = "fitline_F" lineattrs=(color=green thickness=1px pattern=1);
···
···
endlayout;
第二种方法,提前设置好分组变量每一个值对应的Scatterplot和Regressionplot属性,出图的时直接调用,这需要discreteattrmap
和discreteattrvar
语句来实现。
使用discreteattrmap
语句创建一个属性映射,该属性映射将图形属性与离散值匹配。属性映射可以与图中的分类变量相关联。设定各分组属性时,选项ignorecase = true
不区分分组变量的大小写;当然,最好设置离散值与分组变量值一致。Scatterplot是点图,属性设置使用markerattrs
选项,这里设置好颜色 (color)和形状 (symbol);Regressionplot是线图,属性设置使用lineattrs
选项,这里设置好颜色 (color)。
使用 discreteattrvar
语句在已定义的属性映射和包含对应分类值的分类变量之间创建一个关联。attrvar=
选项指定属性映射的关联名称,var=
选项指定输入列,attrmap=
指定已经定义好的属性映射名称。
具体如何应用?在Template绘图语句中,group=
选项使用已经关联组别属性映射的名称,如以下示例代码种的group = groupmarkers
、 group = groupcolors
。
***define the attribute map and assign the name "symbols" and "colors";
discreteattrmap name = "symbols" / ignorecase = true;
value "m" / markerattrs=(color=green symbol=circle);
value "f" / markerattrs=(color=red symbol=triangle);
enddiscreteattrmap;
discreteattrmap name = "colors" / ignorecase = true;
value "m" / lineattrs=(color=green );
value "f" / lineattrs=(color=red );
enddiscreteattrmap;
***associate the attribute map with input data column Sex and assign the name "groupmarkers" "groupcolors" to the named association;
discreteattrvar attrvar = groupmarkers var = sex attrmap = "symbols";
discreteattrvar attrvar = groupcolors var = sex attrmap = "colors";
layout overlay/
···
···
scatterplot y = height x = weight / group = groupmarkers name = "scatter";
regressionplot y = height x = weight / group = groupcolors name = "fitline";
···
···
endlayout;
因为第一种方法,需要对class数据集变量进行重新整理,这里就不进行演示操作了,直接看第二种方法的输出结果。
4. 图形中的图标中相关数值的设置
目前图形的外观设置,已经与例图一致。下面要在图标中添加人数、相关系数以及相应的假设检验P值。根据footnote信息,这里的相关系数是Speaman相关系数。使用Corr过程步来获取n、Spearman相关系数以及对应的P值,并将这些信息整理的数据集corr_all_
中。
***Get n, corr, Spearmanrr;
ods output SpearmanCorr=pp;
proc corr data = class spearman nomiss outp=CorrOutp;
var weight;
with height;
by sex;
run;
ods output close;
data corr_all_;
merge PP( rename=(weight=rr) keep = sex weight )
pp( rename=(Pweight=pval) keep=sex Pweight)
CorrOutp(where=(_type_ = "N") rename=(weight=N) keep = sex weight _type_);
by sex;
length pvalc cvarc nc $20;
if pval=. then pvalc = "NE";
else if .<pval<0.001 then pvalc = "<0.001";
else if pval > 0.1 then pvalc = compress(put(pval, 5.2));
else pvalc = compress(put(pval, 5.3));
cvarc = strip(put(rr, 8.2));
nc=strip(put(n,8.));
keep sex pvalc cvarc nc;
run;
得到对应的统计量数值后,将其保存到宏变量中,方便引用。
proc sql;
select catx(", ", catt( "Female (n=", nc )
,catt( "Correlation Coefficient=", cvarc )
,catt( "Pvalue=", pvalc,")" )
)
into: ncp_f from corr_all_ where sex = "F";
select catx(", ", catt( "Male (n=", nc )
,catt( "Correlation Coefficient=", cvarc )
,catt( "Pvalue=", pvalc,")" )
)
into: ncp_m from corr_all_ where sex = "M";
quit;
宏变量数值如下:
下面考虑如何将统计量的信息放到图标(Legend)中。因为前面根据分组变量Sex的值设置过属性映射,这里就不将宏变量的值保存Sex中了。直接定义新的图标项,然后显示。
legenditem type=marker name="F" /label = "%sysfunc(strip(&ncp_f.))" markerattrs = (color=red symbol=triangle);
legenditem type=marker name="M" /label = "%sysfunc(strip(&ncp_m.))" markerattrs = (color=green symbol=circle);
layout overlay/
···
···
discretelegend "F" "M" / displayclipped=true across=2 border=false;
···
···
endlayout;
我们来看一下,这样设置后的输出结果:
新出的图形中图标超出图形的显示范围,这里有3种解决问题的方法:
- 第一种方法,将图标设置为每行放置1个;
layout overlay/
···
···
discretelegend "F" "M" / displayclipped=true border=false across=1;
···
···
endlayout;
- 第二种方法,改变图标label的大小,使其可以1行放置2个;
legenditem type=marker name="F" /label = "%sysfunc(strip(&ncp_f.))" labelattrs=(size=6pt) markerattrs = (color=red symbol=triangle);
legenditem type=marker name="M" /label = "%sysfunc(strip(&ncp_m.))" labelattrs=(size=6pt) markerattrs = (color=green symbol=circle);
- 第三种方法,改变图形的长宽比,增加宽度,使其可以1行放置2个图标;
ods graphics on /reset =all height= 6in width= 10in ;
proc sgrender data=class template=scatterplot;
run;
ods graphics off;
以上就是临床试验某项目中,散点图的实现过程。如有疑问,欢迎留言反馈!