SAS 程序冷知识——获取数据集观测

数据集观测的获取有2个特别简单的方法,SAS内置了两个系统宏变量,一个叫sqlobs,一个叫sysnobs。

sqlobs:这个宏变量可以获取上一次sql运行的后的观测数。但前提是sql运行必须有结果,所谓结果包括:生成数据集,在结果窗口产生了表格(可以因为观测是0没有结果),产生了宏变量(select into的方法只要能获得多行宏变量就可以)。

举例说明,这样的代码sqlobs的结果永远为1,而不会产生正确结果:

proc sql noprint;

select * from sashelp.class;

quit;

因为即没有数据集产生(比如create table语句),也没有果窗口产生的表格(因为有noprint),也没有宏变量。

下面的代码,sqlobs的结果也是1:

proc sql noprint;

select age into:age from sashelp.class;

quit;

因为虽然产生了宏变量,但是这个宏变量的值只是第一行的值。如果要产生正确结果,只要用separated by就可以了,或者其他能获取多行的方法。

这个宏变量的原理应该是sas会记录扫描过得观测数,所以如果没有数据集,结果窗口的表格,或者宏变量,sas根本不会去扫描结果的观测,所以也就会返回一个1了事。

有意思的是如果你在定义宏变量时指定了个数,比如下面代码,这个宏变量的值就会是2:

proc sql noprint;

select age into:age1-:age2 from sashelp.class;

quit;

因为你只是指定了两个宏变量,所以SAS也就会扫描2行,而实际显然不是2个结果。

sysnobs:这个宏变量可以获取任何过程步结果。对于所有最后生成数据集的过程步,该宏变量获取的是最后生成数据集的观测数。如果没有生成数据集,那么他获取的是输入数据集的观测数。如果生成了数据集但没有观测,他的值是-1.

这个宏变量涉及到两个问题,第一个是当生成多个数据集的时候,他的值是哪个数据集的观测数。第二个是where和这个宏变量谁先执行的问题。

先说第一个,sysnobs永远是最后一个生成的数据集,尽管在一个过程部内,这个规则也是成立的。比如

data class1 class2;

set sashelp.class;

if age>12 then output class2;

output class1;

run;

%let n=;

%let n=&sysnobs.;

%put sysnobs=&n.;

结果为12。因为class2是后生成的,所以是以class2为准的。

再说第二个,比如以下两段代码,结果应该是多少呢?

代码1:

data _null_;

set sashelp.class(where=(age>12));

run;

或者

data _null_;

set sashelp.class;

where age>12;

run;

class本来有19条,其中满足大于12岁的有12条。如果是sysnobs先执行,那么结果应该是19,如果where先执行结果是12.

代码2:

data class(where=(age<=16));

set sashelp.class;

run;

这里是相同的问题,只不过一个是输入数据集,一个是输出数据集。如果sysnobs先执行,那应该是19条,如果where先执行,结果是12条。

经过测试,sysnobs永远是先于where执行的,所以以上的所有结果都是19条。

但是需要注意,下面的结果是12条:

data class;

set sashelp.class;

where age>12;

run;

因为where是对输入数据集的筛选,而最后的生成数据集并没有被where筛选。

你可能感兴趣的:(SAS 程序冷知识——获取数据集观测)