EN
【技术】玫瑰要送对,SET要成对——顺序访问与随机访问结合案例分享
2023-07-28 09:18

作为一名临床研究行业的SAS程序员,我们最主要的工作便是与SAS数据集打交道,掌握对数据集的“任意操纵”技能是必不可缺的。

 

日常工作中,我们发现被很多人称为第四代编程语言(4GL)的SAS语言,在Data步遍历数据集的操作中,表面看没有其它语言中显式的循环+索引的痕迹,同时提供了很多便于横向操作的数据库语言的特性,但在需要索引值进行数据的纵向操作时却遇到了一些阻碍,这种时候,我们往往会考虑通过转置数据集进行横向操作来解决。

 

于是我们会发现,仅仅是简单地访问下一条观测就要进行多步复杂的操作,而这又不太符合编程的至简原则。在这种情况下,顺序访问与随机访问结合就可以完美地解决这个问题。下面小编为大家展示顺序访问与随机访问相结合的一个小示例。

 

今天我们找了来自SASHELP一个班的同学,如果我希望每个男孩都能手捧玫瑰送给他身后的女孩时,那么应当施以什么样的规则呢?

 

640.png

 

可以看到,他们以不太规律的方式依次站列着,当下,我们只希望每位Male可以赠予他身后的Female 一束玫瑰,至于身前没有Male的Female,那暂时就不送她了,谁让她躲在人群之后呢?

 

那么问题来了,我们如何得知哪一位Male身后有一位Female呢?在程序处理中,我们经常会使用lag函数或者retain语句来保留上一条记录的某些特征,不过set语句是从前向后正序遍历的,为了达到获取下一条记录的某种特征,我们可以逆序遍历,之后再正序处理,比如通过如下程序:

 

640 (1).png

 

可以看到结果:

 

640 (2).png

 

只有Alice、James和John将会收到来自她们身前男士赠予她们的玫瑰。

 

不过这样2次排序3次set似乎显的有些冗余,大部分时候,我们应当避免反复读写数据集。因此我们考虑将set语句的多种读取方式结合起来,获取下一条记录的信息也不再那么麻烦,比如程序如下:

 

640 (3).png

 

可以看到结果数据集:

 

640 (4).png

 

我们得到了与之前相同的结果,相比而言,我们并没有对数据进行反复读取,然而在程序运行效率上却有了一些细微的提升。

 

其中需要说明的是,

 

curobs标志着当前观测在原始数据集的行号;

 

nobs标志着原始数据集的总观测数目;

 

point指示SAS读取数据集的具体某条观测;

 

值得注意的是,当使用point方式读取SAS数据集时不可使用索引或分组等读取方式,也不可使用where等语句,并且需要stop语句主动地结束data步的迭代。不过本例中同时使用了顺序访问的set语句,会在数据集读取结束后主动地结束迭代,因此可以不必使用stop语句。

 

在日常的工作中,我们很多地方会用到这种逻辑,比如对于受试者的某些特征,需要前后多条记录去综合判定,希望本文能给予大家启发和帮助。


我们如何帮您呢?凯莱英临床(凯诺)专业团队为您尽快提供服务