BookmarkSubscribeRSS Feed
BrahmanandaRao
Lapis Lazuli | Level 10
data _null_;
set sashelp.class end=last;
if _n_= last then output;
put last=;
run;

I want last observation as per the above code 

william 

10 REPLIES 10
yabwon
Onyx | Level 15

Two things:

1) `end=` allows only two values: 0 when not in the last observation and 1 when in the last observation so use it like this:

data _null_;
set sashelp.class end=last;
if 1 = last then output;
put last=;
run;

2) Remember thai `_N_` is just an "information keeping variable" not the actual number of main loop iteration, so using it in such code is not always good idea, look at this example:

data _null_;
set sashelp.class end=last;
_N_ = 42;
if _n_= last then output;
put _N_= last=;
run;

 

All the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



BrahmanandaRao
Lapis Lazuli | Level 10
i tried with below code
only i want get last observation
data _null_;
set sashelp.class end=last;
if 1=last then do ;
put name=; end;
run;
PaigeMiller
Diamond | Level 26

The first block of code from @yabwon should work perfectly. You made changes and so it doesn't do what you want.

--
Paige Miller
mkeintz
PROC Star

@BrahmanandaRao :

 

Others have shown you how to properly use the dummy variable LAST to test whether the record in hand is the last one in the data set.

 

Your initial concept was to test the condition "_N_=last".   You could use _N_ in your test with another argument of the SET statement (the "nobs" argument), as here:

data want;
  set sashelp.class   nobs=nrecs;
  if _n_= nrecs then output;
run;

 

But one downside of this approach, and also in the "if last=1" approach is that you have to read the entire dataset to get to the last one - trivial for sashelp.class, but expensive for a billion observations read sequentially.  Instead you can do a direct read of the last observation as below:

 

data _null_;
  set sashelp.class nobs=nrecs point=nrecs;
  put name=;
  stop;
run;

This skips to the last record of the dataset with the very first iteration of the data step by using the POINT= option for direct (as opposed to sequential) access.  The only thing to be aware of is the fact that the data step would not automatically stop - because the SET statement would never attempt to read beyond the end of sashelp.class.  So, as you can see, I have programmed a STOP statement.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
yabwon
Onyx | Level 15

Mark ( @mkeintz ) 

 

I like your "point=" and totally agree with the approach. It's definitely way more efficient than my proposition with 1=end.

 

I have one "side note" idea. It would be nice to have the ability to read datasets backward with something like 

set  sashelp.class(backward=yes)

don't you think?

 

All the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



mkeintz
PROC Star

@yabwon wrote: 


I like your "point=" and totally agree with the approach. It's definitely way more efficient than my proposition with 1=end.

 

I have one "side note" idea. It would be nice to have the ability to read datasets backward with something like 

set  sashelp.class(backward=yes)

don't you think?

Yes, but I wonder whether disk file storage systems support efficient performance of reading files backwards. I think there would have to be either

  (1) a list of every disk block address in data record order, presumably easily reversed, or 
  (2) backward links from each block to the previous block.

I am pretty ignorant of disk files systems, so I don 't know the answer to my question.

 

But I do know that this could never have been implemented in early usage of SAS, when data sets were as often read from magnetic tape as from disks.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Kurt_Bremser
Super User

To read a file in reverse, or enable quick random access, you have to load the allocation chain into memory and use it as a linked list; basically, what a hash iterator does.

With Windows, you read the chain from the allocation table, in UNIX, fro the inode table.

Astounding
PROC Star

I like the @mkeintz approach, and would use his point= suggestion if I were programming this myself.  However, I find that sometimes it's easier to understand an approach that is similar to what you have already programmed.  If were look at that, the changes needed would be simple:

data _null_;
set sashelp.class end=last;
if _n_= last then output;
put last=;
run;

We can just remove a few words here and there to come up with a data set holding just the last observation:

data last_observation_only;
set sashelp.class end=last;
if last;
run;

If it better suits what you are trying to do, you can use _NULL_ as the data set name and add a PUT statement just before the RUN statement.

RichardDeVen
Barite | Level 11

The END= option specifies the name of an automatic flag variable that will contain the state of the most recent read performed by the SET statement.  A flag variable is numeric and has value 0 meaning false and 1 meaning true. Automatic variables are part of the program data vector (PDV) but tacitly dropped from the output data set.  The state communicated by the variable is the concept 'no more records after this one' or 'that was the last record'

 

Example:

 

* Read each record and output the last one;
data want; set have end=last; if last; * subsetting if; * implicit output; run;

 

 

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 10 replies
  • 9682 views
  • 10 likes
  • 7 in conversation