DATA Step, Macro, Functions and more

SYSNOBS automatic macro variable

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 8
Accepted Solution

SYSNOBS automatic macro variable

Hi All,

About SYSNOBS automatic macro variable

SAS(R) 9.3 Macro Language: Reference

 

I dont understand that "Note: If the number of observations for the data set was not calculated by the previous procedure or DATA step, the value of SYSNOBS is set to -1."

What does this mean ?

Can i get any sample code ?

Thanks.


Accepted Solutions
Solution
‎12-11-2013 01:24 PM
Super Contributor
Posts: 339

Re: SYSNOBS automatic macro variable

Thanks DN

Well it appears my expectation based on documentation were miles off!

It appears to only consider the last output dataset despite the fact that it doesn't actually "read" that DS but only write it - it still reads its number of observations I guess.

Thus it behaves significantly closer to the &SQLOBS automatic macro than I expected.

data _null_; should always return 0.

@Amats, this explains why your data 1aa; run; empty data step returns 0 instead of 1. A file or dataset is actually created with 0 data records so the file was opened/closed and thus a number of observations output is retrieved.

If you reuse the _1 dataset defined above to compare with SQL, you will see the behavior is the same for empty queries.

953  proc sql;
954      select x
955      from _1
956      where x>3
957      ;
NOTE: No rows were selected.
958  quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           1.68 seconds
      cpu time            0.01 seconds


SYMBOLGEN:  Macro variable SQLOBS resolves to 0
959
960  %put &sqlobs;
0

So since it behaves on output and doesn't *seem to* care for input data that is read and for which a file was opened/closed through the step/procedure, I would assume that the reason your proc datasets had a value of &SYSNOBS=0 and not -1 is because the procedure itself is able to produce an output but since you did not use the out= option to output the results of the proc datasets to a file, the net number of records output is 0. That would allow to distinguish from, say, proc setinit; run; that are procedures without output that should result in a -1 code for &SYSNOBS (I couldn't think of any better documented procedure without output on the fly, sorry).

Sidethought: I wonder if it is possible to use symget immediately after a hash object .output method to see if it is updated then not that it is necessary, num_items method can achieve that anyway.

View solution in original post


All Replies
Super Contributor
Posts: 276

Re: SYSNOBS automatic macro variable

If Previous Procedure or Datastep failed to execute due to some errors,that time value of SYSOBS is set to -1.

Thanks,

Sanjeev.K

Occasional Contributor
Posts: 8

Re: SYSNOBS automatic macro variable

Hi, Sanjeev.


I get the result "0" when running the below code.

Why it doesn't return "-1" ?

data 1aa;

run;

%put OBS=&sysnobs;

Super Contributor
Posts: 276

Re: SYSNOBS automatic macro variable

Ahh i see,

I understand in that way,

Can you try writing Data _null_;run;,or just run Proc Datasets;run and check the value of the sysnobs?? I don't have SAS 9.3 access right now...

Thanks,

Sanjeev.K


Occasional Contributor
Posts: 8

Re: SYSNOBS automatic macro variable

I tried all of your suggestions,

but it all returns "0"...

Super Contributor
Posts: 339

Re: SYSNOBS automatic macro variable

I don't have 9.3 on my current machine to test but from the description and my understanding of data step help wording conventions, I would assume it mimics the &SQLOBS with some limitations so if there is no SET statement in a data step, the value returned should be 0 as no the only dataset in an empty data step is that of the output but no observations are READ from the output datasets.

Similarly, I think proc datasets use VTABLES which are really only views and thus technically don't directly open a data set to read in the values. I'm not entirely sure why it doesn't output -1 though I'd have to get on a 9.4 test tower at work to run tests and someone else will likely provide a detailed answer before then but for data step functionalities, I suggest you test the following

data _1;

     x=1;

run;

%put &sysnobs; /* should be 0 if my understanding is correct */

data _2;

     x=1; output; x=2; output;

run;

%put &sysnobs; /* should be 0 as well */

data _1_2;

     set _1 _2;

run;

%put &sysnobs; /* should be either 2 or 3 depending if it considers the entire set statement entity as a single "opened dataset" */

/* create views for each _1 and _2 call them v_1 and v_2 for simplicity */

data _null_;

     set _1;

run;

%put &sysnobs; /* should be 1 */

data _null_;

     set v_1;

run;

%put &sysnobs; /* will likely be 0 that would explain the proc datasets results - if not, repeat with v_2 */

data _null_;

     set _2(where=(x=1));

run;

%put &sysnobs; /* should be 1 as technically where statements within the set statement are more efficient than where statements within the data step as it skips reading the record entirely */

With the above, it should give you insight on what to expect from various "usual" procedures but odds are you'd need to do tests on a per procedure basis to really understand how it works. In general, I would expect it to return the number of physical observations attached to the dataset tied to the DATA= statement for procedures that have that in their statement options.

ultimately, I suppose it's main use or purpose is to get the number of physical observations from sets located on a rdbms where you can't use nobs or nlobs from the sashelp.vtable to get the information.

Respected Advisor
Posts: 3,777

Re: SYSNOBS automatic macro variable

17         GOPTIONS ACCESSIBLE;
18         data _1;
19              x=1;
20         run;

NOTE:
The data set WORK._1 has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.01 seconds
     

21         %put NOTE:  &=sysnobs; /* should be 0 if my understanding is correct */
NOTE:  SYSNOBS=
1
22        
23         data _2;
24              x=1; output; x=2; output;
25         run;

NOTE:
The data set WORK._2 has 2 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.01 seconds
     

26         %put NOTE:  &=sysnobs; /* should be 0 as well */
NOTE:  SYSNOBS=
2
27        
28         data _1_2;
29              set _1 _2;
30         run;

NOTE:
There were 1 observations read from the data set WORK._1.
NOTE: There were
2 observations read from the data set WORK._2.
NOTE: The data set WORK._1_2 has
3 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     

31         %put NOTE:  &=sysnobs; /* should be either 2 or 3 depending if it considers the entire set statement entity as a single
31       ! "opened dataset" */

NOTE:  SYSNOBS=
3
32        
33        
34         /* create views for each _1 and _2 call them v_1 and v_2 for simplicity */
35        
36         data v_1 / view=v_1;
37              set _1;
38         run;

NOTE:
DATA STEP view saved on file WORK.V_1.
NOTE: A stored DATA STEP view cannot run under a different operating
system.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     

39         %put NOTE:  &=sysnobs; /* should be 1 */
NOTE:  SYSNOBS=
1
40        
41         data _null_;
42              set v_1;
43         run;

NOTE:
View WORK.V_1.VIEW used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     
NOTE: There were
1 observations read from the data set WORK._1.
NOTE: There were
1 observations read from the data set WORK.V_1.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     

44         %put NOTE:  &=sysnobs; /* will likely be 0 that would explain the proc datasets results - if not, repeat with v_2 */
NOTE:  SYSNOBS=-
1
45        
46         data c;
47            set v_1;
48            run;

NOTE:
View WORK.V_1.VIEW used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     
NOTE: There were
1 observations read from the data set WORK._1.
NOTE: There were
1 observations read from the data set WORK.V_1.
NOTE: The data set WORK.C has
1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     


49         %put NOTE:  &=sysnobs; /* will likely be ? */
NOTE:  SYSNOBS=
1
50        
51        
52        
53         data _null_;
54              set _2(where=(x=1));
55         run;

NOTE:
There were 1 observations read from the data set WORK._2.
      WHERE x=
1;
NOTE:
DATA statement used (Total process time):
      real time          
0.00 seconds
      cpu time           
0.00 seconds
     

56        
57         %put NOTE:  &=sysnobs; /* should be 1 as technically where statements within the set statement are more efficient than
57       ! where statements within the data step as it skips reading the record entirely */

NOTE:  SYSNOBS=
2
58        
59        
60         GOPTIONS NOACCESSIBLE;
61         %LET _CLIENTTASKLABEL=;
62         %LET _CLIENTPROJECTPATH=;
63         %LET _CLIENTPROJECTNAME=;
64         %LET _SASPROGRAMFILE=;
65        
66         ;*';*";*/;quit;run;
67         ODS _ALL_ CLOSE;
68        
69        
70         QUIT; RUN;
71        
Solution
‎12-11-2013 01:24 PM
Super Contributor
Posts: 339

Re: SYSNOBS automatic macro variable

Thanks DN

Well it appears my expectation based on documentation were miles off!

It appears to only consider the last output dataset despite the fact that it doesn't actually "read" that DS but only write it - it still reads its number of observations I guess.

Thus it behaves significantly closer to the &SQLOBS automatic macro than I expected.

data _null_; should always return 0.

@Amats, this explains why your data 1aa; run; empty data step returns 0 instead of 1. A file or dataset is actually created with 0 data records so the file was opened/closed and thus a number of observations output is retrieved.

If you reuse the _1 dataset defined above to compare with SQL, you will see the behavior is the same for empty queries.

953  proc sql;
954      select x
955      from _1
956      where x>3
957      ;
NOTE: No rows were selected.
958  quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           1.68 seconds
      cpu time            0.01 seconds


SYMBOLGEN:  Macro variable SQLOBS resolves to 0
959
960  %put &sqlobs;
0

So since it behaves on output and doesn't *seem to* care for input data that is read and for which a file was opened/closed through the step/procedure, I would assume that the reason your proc datasets had a value of &SYSNOBS=0 and not -1 is because the procedure itself is able to produce an output but since you did not use the out= option to output the results of the proc datasets to a file, the net number of records output is 0. That would allow to distinguish from, say, proc setinit; run; that are procedures without output that should result in a -1 code for &SYSNOBS (I couldn't think of any better documented procedure without output on the fly, sorry).

Sidethought: I wonder if it is possible to use symget immediately after a hash object .output method to see if it is updated then not that it is necessary, num_items method can achieve that anyway.

Respected Advisor
Posts: 3,777

Re: SYSNOBS automatic macro variable

The value after compiling a view is interesting.

26         data x; stop; run;

NOTE:
The data set WORK.X has 0 observations and 0 variables.

27         %put NOTE &=sysnobs;
NOTE SYSNOBS=0
28         data bv / view=bv;
29            set sashelp.class(obs=3) sashelp.class(obs=4);
30            run;

NOTE:
DATA STEP view saved on file WORK.BV.
NOTE: The original source statements cannot be     

31         %put NOTE &=sysnobs;
NOTE SYSNOBS=19
Occasional Contributor
Posts: 8

Re: SYSNOBS automatic macro variable

Thank you all, I got it!

=====================================================================

p.s.

I get the following result,

I think, SYSNOBS doesn't seem affected by SETINIT procedure,

===Code1=====

data _1;

  x=1;

run;

proc setinit; run;

%put OBS=&sysnobs;

===Log======

OBS=1

===Code2=====

data _2;

  x=1;output; x=2;output;

run;

proc setinit; run;

%put OBS=&sysnobs;

===Log======

OBS=2

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 9 replies
  • 1563 views
  • 5 likes
  • 4 in conversation