vlambda博客
学习文章列表

数据集快速排序 trick

马不停蹄赶稿子。

问题

有如下数据集,需要固定其中 stat 列的顺序,

啥意思?就是后面不管这个数据集如何排序,要保持,在各个 sex 中,stat 始终保持 N->Mean->std->Median->Minimum->Maximum 这样的顺序不变。

厘清思路

这里我们用到了 dow 循环来操作,对于这种由 proc means 确定的 stat 顺序的 situation,dow 循环是再合适不过的了。

上 code,

data mean3;
do _n_= 1 by 1 until(last.sex);
set mean2;
by cat sex var;
ord= _n_;
output;
end;
run;

就是如此简单。实际上,我们在 文章里提到过 dow 循环。

注意看过程,其中,当读完第一个 by 变量组的全部观测时,last.sex 判定 do until 循环终止,data step 的第一次迭代结束,进入 data step 的第二次迭代,do until 的 _n_ 又从 1 开始,直到 last.sex,依次类推。我们可以发现,一次 data step 的循环迭代,读取的就是 一个 by 变量组的全部观测。

提问,这里的 do _n_ by until,你觉得起到什么作用?实际上,它压缩了经由 set 读取数据时 data step 的循环迭代次数。为什么这么说?正常来讲,

data mean3;
set mean2;
by cat sex var;
run;

这里,data step 需要迭代 18 次的,而由于 dow 循环控制了一次 data step 终止的条件,即,必须遇上 last.sex,该次 data step 的迭代才能终止,因而,data step 最终只需要迭代 3 次,即可读入全部观测,同时借助 _n_ 作为计数器,完成了行观测顺序的 assignment。

这种方式,实现了对数据读取的更大程度的控制,非常推荐日常多多使用。

细节

肯定有人要问,如果开始的数据集 stat 列不是刚好我们要的顺序怎么办?

有人就想着利用 if then,进行顺序的一个个赋值,当然是可行的,但是一旦 if condition 过多,写起来也很麻烦,这里推荐的另外一个方式是 这篇文章里提到的,借助 proc format,将 stat 生成数字 format,依据数字进行排序,同时若要对 stat 中的值改名,只需要再生成第二个字符串 format,后续进行转 format 即可。