BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
jojozheng
Quartz | Level 8

Hi,

 

I have a dataset like this

 

n    date
1 31AUG2018 

2 30JUN2018
3 31MAR2018
4 31DEC2017
5 30SEP2017
6 30JUN2017
7 31MAR2017

proc sql noprint;/*assign macro variable as_of_date*/
select catx('', quote(put(date, date9.)), 'd'),catx('', quote(put(date, date9.)), 'd'),n
into :dates1-,
:as_of_date separated by ',',
:n1-
from z;
%let n=&n;
%let as_of_date=(&as_of_date);
%let dates=&dates;

 

I want to assign last obs n=7, date=31MAR2017. since last n will change, it's not a fix number, it can be any number, this example gives last n=7. So how can I assign last n return to corresponding date??

 

Thanks! 

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

I believe you simply need to retrieve the macrovar &SQLOBS, produced by the proc sql.

 

I.e. simply use

 

   %let n=&sqlobs;

--------------------------
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

--------------------------

View solution in original post

8 REPLIES 8
mkeintz
PROC Star

I believe you simply need to retrieve the macrovar &SQLOBS, produced by the proc sql.

 

I.e. simply use

 

   %let n=&sqlobs;

--------------------------
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

--------------------------
jojozheng
Quartz | Level 8
thank you ! it works!
Reeza
Super User

Or do it in a data step which is trivial. Use either END if you want the last observeration only or use LAST. if you need the last by each group.

 

data _null_;
set sashelp.stocks (where=(stock='IBM')) end=eof;
if eof then 
call symputx('last_date', put(date, date9.));
run;

%put &last_date.;

Note in the sashelp.stocks data set the dates are in reverse order, so the last date on record is actually the earliest date. 

 


@jojozheng wrote:

Hi,

 

I have a dataset like this

 

n    date
1 31AUG2018 

2 30JUN2018
3 31MAR2018
4 31DEC2017
5 30SEP2017
6 30JUN2017
7 31MAR2017

proc sql noprint;/*assign macro variable as_of_date*/
select catx('', quote(put(date, date9.)), 'd'),catx('', quote(put(date, date9.)), 'd'),n
into :dates1-,
:as_of_date separated by ',',
:n1-
from z;
%let n=&n;
%let as_of_date=(&as_of_date);
%let dates=&dates;

 

I want to assign last obs n=7, date=31MAR2017. since last n will change, it's not a fix number, it can be any number, this example gives last n=7. So how can I assign last n return to corresponding date??

 

Thanks! 


 

DBailey
Lapis Lazuli | Level 10

You could separate the n/as of date from the other date query as

 

select n, date
into :n, :as_of_date
from z
where n = (select max(n) from z);

Reeza
Super User
data have;
informat ID 8. date date9.;
input ID date;
cards;
1 31AUG2018 
2 30JUN2018
3 31MAR2018
4 31DEC2017
5 30SEP2017
6 30JUN2017
7 31MAR2017
;
run;

data want;
set have end=eof;
call symputx(catt('dates', put(_n_, 8. -l)), catt(quote(put(date, date9.)), 'd'));
if eof then do;
call symputx('n', put(_n_, 8. -l));
call symputx('as_of_date', catt(quote(put(date, date9.)), 'd'));
end;
run;

%put &dates1.;
%put &dates7.;
%put &n.;
%put &as_of_date.;

 Full data step approach

 


@jojozheng wrote:

Hi,

 

I have a dataset like this

 

n    date
1 31AUG2018 

2 30JUN2018
3 31MAR2018
4 31DEC2017
5 30SEP2017
6 30JUN2017
7 31MAR2017

proc sql noprint;/*assign macro variable as_of_date*/
select catx('', quote(put(date, date9.)), 'd'),catx('', quote(put(date, date9.)), 'd'),n
into :dates1-,
:as_of_date separated by ',',
:n1-
from z;
%let n=&n;
%let as_of_date=(&as_of_date);
%let dates=&dates;

 

I want to assign last obs n=7, date=31MAR2017. since last n will change, it's not a fix number, it can be any number, this example gives last n=7. So how can I assign last n return to corresponding date??

 

Thanks! 


 

data_null__
Jade | Level 19

If you just need to access the last obs you can point to it directly.

 

34   data _null_;
35      set have point=nobs nobs=nobs;
36      put _all_;
37      stop;
38      run;

nobs=7 ID=7 date=31MAR2017 _ERROR_=0 _N_=1

 

Deleted records disclaimer given.

Reeza
Super User
Agreed, except OP also wants a macro variable for each obs.
s_lassen
Meteorite | Level 14

I am not quite sure that I understand your requirements, but from your code it looks like you are trying to do something like this:

proc sql noprint;
  select n,date into :n1-:n999,:date1-:date999
  from have
  order by n;
quit;

%let last=&sqlobs;
%let last_n=&&n&last;
%let as_of_date=&&date&last;

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 2247 views
  • 7 likes
  • 6 in conversation