BookmarkSubscribeRSS Feed
Obsidian | Level 7

I'm trying to count the number of observations in a dataset, accounting for WHERE clauses and the FIRSTOBS and OBS options. So, I open the dataset and read the NLOBSF attribute with the attrn function. However, the count that I get does not account for FIRSTOBS or OBS. Here's an example program, using the sashelp.class dataset, which has 19 total observations:


* macro to count the number of observations in a dataset using the NLOBSF attribute;
%macro check(dsn);
	%let dsid = %sysfunc(open(&dsn));
	%if &dsid = 0 %then %do;
		%put %sysfunc(sysmsg());

	%put nlobsf = %sysfunc(attrn(&dsid,NLOBSF));
	%let rc = %sysfunc(close(&dsid));

options firstobs=1 obs=max; * set firstobs and obs to system defaults;

%check(sashelp.class); * count all observations -> gives 19 obs (correct);
%check(sashelp.class(where=(name=:'J'))); * names starting with J -> gives 7 obs (correct);
%check(sashelp.class(firstobs=10)); * skip the first 9 obs -> gives 19 obs (wrong!);
%check(sashelp.class(obs=10)); * only the first 10 obs -> gives 19 obs (wrong!);

options obs=10;
%check(sashelp.class); * only the first 10 obs -> gives 19 obs (wrong!);

* with the obs=10 option in effect, this data step correctly reads in only 10 obs;
data _null_;
	set sashelp.class;


I get the correct total count when not subsetting. I also get the correct count when using a WHERE clause. But the code fails when using FIRSTOBS or OBS, either as a dataset-option or as a system option. Is this a bug in SAS, or am I doing something wrong / misunderstanding something?


FYI, I'm using SAS 9.4 (TS1M3). Here's the SAS 9.4 help file description of the NLOBSF attribute:

specifies the number of logical observations (the observations that are not marked for deletion) by forcing each observation to be read and by taking the FIRSTOBS system option, the OBS system option, and the WHERE clauses into account.

Super User Tom
Super User

Interesting, but what question are you trying to answer by querying the NOBS, NLOBS or NLOBSF metadata?


It sounds like it is returning the count of observations in the database and you want to know the number of observations that would be read if you tried to query in a way where all of these other external options could potentially change how many observations are actually used.


If you want the latter then you probably will get the best results using PROC SQL to run COUNT(*) on the dataset.

Obsidian | Level 7

My goal is to create a reusable macro function that returns the number of observations in a dataset, accounting for any subsetting options. Although I could use proc sql as you suggest, I was hoping to use only macro code, so that I can call my function inline, e.g.

title "Characteristics of male students, N = %nobs(sashelp.class(where=(sex='M')))";

where %nobs is the function I'm creating. This example would actually work, because WHERE clauses are handled correctly using NLOBSF. But if for some reason I wanted to subset with FIRSTOBS or OBS, the code wouldn't work as is, even though the documentation suggests that it should.

Super User Tom
Super User

It does appear to NOT honor either system or dataset options for OBS or FIRSTOBS.

If you care about that then perhaps you can make your macro check the system settings using GETOPTION() function and scan the dataset parameter value for OBS= or FIRSTOBS= option.  You could then have the macro use FETCH() to read the observations one by one and count.

You can see an example of how to do the counting in this macro


Tourmaline | Level 20

The documentation is pretty clear: the FIRSTOBS system option, the OBS system option, and the WHERE clause should be taken into account.


If I were you, I'd definitely ask tech support to open a defect.


Having said that, your macro is mostly useful for discovering data with a where clause applied.

The fact that options FIRSTOBS and OBS are ignored does not diminish its usefulness much, imho.






Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.


Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 3 in conversation