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.
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.
If Previous Procedure or Datastep failed to execute due to some errors,that time value of SYSOBS is set to -1.
Thanks,
Sanjeev.K
Hi, Sanjeev.
I get the result "0" when running the below code.
Why it doesn't return "-1" ?
data 1aa;
run;
%put OBS=&sysnobs;
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
I tried all of your suggestions,
but it all returns "0"...
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.
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.
The value after compiling a view is interesting.
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
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.