简体   繁体   中英

SAS Return data from the last available 5 days

I have a list of intra-day prices at 9am, 10am, 11am etc. for each day (which are in number formats such as 15011 15012 etc.)

I want to only keep the observations from the last available 5 days and the next 5 available days from the date 't' and delete everything else. Is there a way to do this?

I tried using if date < &t - 5 or date > &t + 5 then delete; However, since there are weekends/holidays I don't get all the observations I want.

Thanks a lot in advance!

Not much info to go on, but here is a possible solution:

/* Invent some data */
data have;
  do date=15001 to 15020;
     do time='09:00't,'10:00't,'11:00't;
        price = ranuni(0) * 10;
        output;
        end;
     end;
run;

/* Your macro variable identifying the target "date"  */
%let t=15011;

/* Subset for current and following datae*/
proc sort data=have out=temp(where=(date >= &t));
   by date;
run;

/* Process to keep only current and following five days */
data current_and_next5;
   set temp;
      by date;
   if first.date then keep_days + 1;  /* Set counter for each day */
   if keep_days <= 6;                 /* Days to keep (target and next five) */
   drop keep_days;                    /* Drop this utility variable */
run;

/* Subset for previous and sort by date descending */
proc sort data=have out=temp(where=(date < &t));
   by descending date;
run;

/* Process to keep only five previous days */
data prev5;
   set temp;
      by descending date;
   if first.date then keep_days + 1;  /* Set counter for each day */
   if keep_days <= 5;                 /* Number of days to keep */
   drop keep_days;                    /* Drop this utility variable */
run;

/* Concatenate together and re-sort by date */

data want;
   set current_and_next5
       prev5;
run;

proc sort data=want;
   by date;
run;

Of course, this solution suggests that your starting data contains observations for all valid "trading days" and returns everything without doing date arithmetic. A much better solution would require that you create a "trading calendar" dataset with all valid dates. You can easily deal with weekends, but holidays and other "non-trading days" are very site specific; hence using a calendar is almost always preferred.

UPDATE: Joe's comment made me re-read the question more carefully. This should return a total of eleven (11) days of data; five days prior, five days following, and the target date. But still, a better solution would use a calendar reference table.

Try this

/* Get distinct dates before and after &T */
proc freq data=mydata noprint ;
  table Date /out=before (where=(Date < &T)) ;
  table Date /out=after (where=(Date > &T)) ;
run ;

/* Take 5 days before and after */
proc sql outobs=5 ;
  create table before2 as
  select Date 
  from before 
  order by Date descending ;

  create table after2 as
  select Date 
  from after 
  order by Date ;
quit ;

/* Subset to 5 available days before & after */
proc sql ;
  create table final as
  select *
  from mydata 
  where Date >= (select min(date) from before2)
    and Date <= (select max(date) from after2)
  order by Date ;
quit ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM