欢迎光临散文网 会员登陆 & 注册

SAS绘图、R绘图(三):平分秋色、各有千秋

2023-08-20 10:38 作者:统计_碎碎念  | 我要投稿

绘图软件简介——R & SAS

  R因其“开源、免费、门槛低”受到越来越多人的青睐,R-package涵盖了许多前沿的统计方法和精美的可视化功能,在科研数据分析中的地位也越来越重要。

  SAS因其卓越的运算性能、稳定的运算架构和强大的数据管理能力受到越来越多专业人士的青睐,广泛运用于医学、统计和数学分析,商业规划,预测运筹优化以及应用开发等。

什么是科研绘图?

  让我们来看看SAS和R的官方是如何介绍自己的绘图模块的,R语言中“ggplot2是一款强大的统计分析及可视化软件包,光是此包的官方文档就足有292页,但SAS则更多,对于其template绘图语句的文档有730页。

  其中官方文档中对“ggplot2”功能描述是这样的:

  Description: A system for 'declaratively' creating graphics, based on ``The Grammar of Graphics''. You provide the data, tell 'ggplot2' how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.

  而SAS则是这样的:

  Description: The Graph Template Language (GTL) is the heart of ODS Graphics. All of the graphs that are created by the SAS analytical procedures and by the SAS statistical graphics procedures are generated using GTL. Users who need to go beyond the graphs created by these SAS procedures can use GTL directly to design their graphs using the TEMPLATE and SGRENDER procedures. To successfully create or modify GTL templates, you need the information in this guide, which helps you understand important concepts and offers many complete code examples that illustrate frequently used features. You also need SAS Graph Template Language: Reference, which is the language dictionary for GTL.

  当然官方文档中更多介绍这里不再罗列,通过阅读和实操体会,自然而然我们可以总结出绘图原理包括以下几个核心概念:

数据映射:首先,将数据集中的变量映射到图形属性上,例如将变量映射到x轴和y轴上,或将变量映射到颜色、形状等图形属性上。通常数据映射是需要经过数据清洗得到的。

统计变换:在绘制图形前,可以对数据进行一些统计变换,例如计算均值、中位数、分位数等。这些统计变换可以用来创建汇总统计图形,如直方图(hist)、散点图(scatterplot)等。可视化的核心目的即为理解数据,发现关联或趋势,传达信息而提出。

几何对象:使用几何对象来表示数据,常见的几何对象有点(point)、线段(line)、条形图(bar)、箱线图(boxplot)等。通过指定绘图的几何对象,可以创建出不同形式的图形。基于目的,用不同几何对象可视化的效果也各不相同。

坐标系统:坐标系统定义了绘图的坐标轴和刻度。R中ggplot可以使用多种类型的坐标系统,如笛卡尔坐标系(cartesian)、极坐标系(polar)等。这使得可视化结果不仅仅局限于二维,还可以是三维或更高维度的展示。

图层(Layer):通过逐层添加几何对象、数据映射和统计变换,可以创建出复杂的图层。每个图层可以有不同的数据映射和统计变换,多个图层叠加在一起,最终形成绘图的结果。不同元素的叠加,都需要有自己的图层,不同元素的图层参照系可以相同,也可以不同。

主题(Theme):主题定义了绘图的样式和外观,包括背景颜色、字体、坐标轴样式等。ggplot允许用户根据需求自定义主题,以创建适应不同风格和需求的图形。主题设置一是为了规范化使用者的可视化结果,二是减少工作量,去除不必要的冗杂代码。


3 代码本质区别?

下面我们使用SAS软件中 sashelp逻辑库下的class数据库作为本篇文章的示例数据集。

SAS code

   数据映射:proc sgplot data= Class 指定映射数据集,vbar Sex / response= Height  group=Sex指定了映射元素以及如何映射。统计变换groupdisplay=cluster ,stat=mean 集中趋势的呈现方式。Vbar代表了误差柱状图,即几何对象xaxis、yaxis即对坐标系统进行了设置,这里调整了字体及其大小。由于此处未使用proc template 选项所以未对图层和主题进行设置。


*设置图形Dpi;

ods html dpi=300;

*设置绘图面板长和宽;

ods graphics / reset noborder height=6in width=5in;

proc sgplot data= SAShelp.Class SGANNO=anno;

  *指定颜色循环;

  styleattrs datacolors=("#ff5500" "#4b71af" ) datacontrastcolors = ("#ff5500" "#4b71af");

  *关键代码;

  vbar Sex / response= Height  group=Sex groupdisplay=cluster CLUSTERWIDTH=0.7 BARWIDTH=0.8  

    stat=mean limits=upper limitstat=STDDEV LIMITATTRS=(color=black thickness=2) LIMITCAPSCALE=0.7

    DISPLAYBASELINE=off TRANSPARENCY=0; 

  *X轴设置;

  xaxis display=(nolabel)

    valueattrs=(size=10 Family="Times New Roman/宋体" Weight=Bold)  

    labelattrs=(size=11 Family="Times New Roman/宋体" Weight=Bold) type=discrete;

  *Y轴设置;

  yaxis label="身高(m)"

    valueattrs=(size=10 Family="Times New Roman/宋体" Weight=Bold) 

     labelattrs=(size=11 Family="Times New Roman/宋体" Weight=Bold) OFFSETMAX=0.2;

  *图例设置;

  keylegend / title="Gender" location=inside down=1 position=TOPright noborder;

run;

quit;

R code:

  数据映射:data=Meanlist, 映射数据集,mapping=aes(x=Sex, y=mean,fill=Sex)指定了映射元素以及如何映射,统计变换:stat="identity"集中趋势的呈现方式。geom_bar和geom_errorbar代表了误差柱状图,即几何对象。theme()即对坐标系统进行了设置,这里调整了字体及其大小。注意此时整个theme模块包含了许多主题参数,并且此时我们先通过geom_bar绘制了柱状图的图层,然后通过geom_signif绘制了差异性检验结果图层,最后通过geom_errorbar绘制了误差图层,这里可以调换绘制顺序,不影响最终绘图效果

 

ggplot()+

  geom_bar(data=Meanlist,mapping=aes(x=Sex,y=mean,fill=Sex), # fill填充

           position="dodge", # 柱状图格式

           stat="identity", # 数据格式

           width = 0.7)+  # 柱状图尺寸

  scale_fill_manual(values = c("#ff5500", "#4b71af"))+ # 柱状图颜色

  geom_signif(data=df,mapping=aes(x=Sex,y=Height), # 不同组别的显著性

              comparisons = list(c("男", "女")),# 哪些组进行比

              annotation="P > 0.05",# 显著性差异做标记

              map_signif_level=T, # T为显著性,F为p value

              tip_length=c(0.04,0.04,0.05,0.05), # 修改显著性那个线的长短

              y_position = 70, # 设置显著性线的位置高度

              size=1, # 修改线的粗细

              textsize = 5, # 修改*标记的大小

              test = "t.test",

              fontface = "italic",

              family = "myFont")+ # 检验的类型

  geom_errorbar(data=Meanlist,mapping=aes(x =Sex,ymin = mean, ymax = mean+sd), # 误差线添加

                width = 0.1, #误差线的宽度

                color = 'black', #颜色

                size=0.8)+ #粗细

  scale_y_continuous(limits =c(0, 80) ,expand = c(0,0))+ # y轴的范围

  theme_classic(  # 主题设置,这个是无线条主题

    base_line_size = 1 # 坐标轴的粗细

  )+

  labs(title="",x="",y="身高(m)",fill = "性别")+ # 添加标题,x轴,y轴内容

   theme(

     # plot.title = element_text(size = 20,colour = "red",hjust = 0.5),

        axis.title.y = element_text(size = 15,  family = "myFont", color = "black",

                                    face = "bold",  vjust = 1.9,  hjust = 0.5,  angle = 90),

        legend.title = element_text(color="black", # 修改图例的标题

                                    size=15,

                                    face="bold"),

        legend.text = element_text(color="black", # 设置图例标签文字

                                   size = 15,

                                   face = "bold"),

        axis.text.x = element_text(size = 15,  # 修改X轴上字体大小,

                                   # family = "myFont", # 类型

                                   color = "black", # 颜色

                                   face = "bold", #  face取值:plain普通,bold加粗,italic斜体,bold.italic斜体加粗

                                   vjust = 0.5, # 位置

                                   hjust = 0.5,

                                   angle = 0), #角度

        axis.text.y = element_text(size = 15,  # 修改y轴上字体大小,

                                   # family = "myFont", # 类型

                                   color = "black", # 颜色

                                   face = "bold", #  face取值:plain普通,bold加粗,italic斜体,bold.italic斜体加粗

                                   vjust = 0.5, # 位置

                                   hjust = 0.5,

                                   angle = 0) #角度

方才我们展示了R和SAS绘图代码并无本质区别,接下来让我们看看两者绘制的图如何。

4 案例—柱状图(误差线+差异性检验)

  这里我们会发现SAS和R代码在绘图原理基础上并无区别,SAS的Porc sgplot并无对主题的设置,这就导致了SAS图的边框无法自定义(如果没有使用template)。

  你能发现哪个是SAS绘图,哪个是R绘图吗?

  针对70%左右的图形,SAS和R可以达到同样的效果。而为了更加方便、批量重复绘图,SAS提供了宏程序功能,下面是笔者撰写的SAS绘制KM曲线和ROC曲线的宏程序(后续本课题组将会持续推出各种SAS绘图以及统计分析的宏程序系列):

绘图效果如下:


5总结:

  在大部分绘图过程中SAS和R是没有本质区别的,区别在对图的精细调整,如果只是想要实现两者绘图效果基本一致,那么SAS的proc sgplot 和 R的 ggplot的绘图效果只取决于你代码的精细程度(甚至可以完全一致)。

  如果想要实现每个细节的调控,SAS必须借助proc template语句进行模版撰写,回头看这也正是SAS绘图官方文档长达720页的主要原因,其对细节的调整不亚于R的ggplot各种函数,只是R把所有的参数全部集中在了ggplot()中。

拓展 高阶SAS绘图

     相信先前大家对于R的高阶绘图或多或少有些了解,部分使用者对于SAS的绘图能力一直以来产生质疑,那现在就给大家展示一下SAS的天花板绘图吧,!当然要绘制出这些图形代码就相对复杂了,代码少则百行,多则千行。对以下所有图有兴趣的同学和老师可以后台联系小助手。

如需以上绘图高阶代码,请后台私信联系!

关注微信公众号,获取更多相关内容!


 

程序编写:想不出吸睛好名字、天涯二毛君

文字编辑:想不出吸睛好名字

审阅:老陈


SAS绘图、R绘图(三):平分秋色、各有千秋的评论 (共 条)

分享到微博请遵守国家法律