sas proc sql - 获取最小日期并添加1年

时间:2016-05-03 15:51:05

标签: sas proc-sql

我有一个带ID的数据集,每个ID都有多个日期(实际上是日期时间)。我想使用PROC SQL来获得最短的日期时间,并将最少1年的时间加起来。我试图在一个PROC SQL中完成这一切,但一直在摸索,无法让这个工作。以下是两次尝试。非常感谢任何建议。

*** GENERATE RANDOM DATES AFTER JAN 1, 2012 AND CREATE DATE/TIME VARIABLE ***;
data have ;
    format date mmddyy10.  dt datetime15.;
    do person_id=100, 200, 300, 400, 500;
    do i = 1 to 100;
        jdate = int(1000 * ranuni(123987));
        date = mdy(1,1,2012) + jdate;
        dt = dhms(date, 0,0,0);
        output;
    end;
    end;
run;

*** TRY1: THIS DOES NOT WORK - GETS MIN DATE/TIME AND REMERGES WITH EVERY RECORD***;
proc sql;
    create table try1 as
    select min(dt) as index_dt  format=datetime15. ,
        (dt + 365*24*60*60) as followup_date  format=datetime15.  
    from have
;
quit;


*** TRY2: USE MIN() IN "HAVING" STATEMENT ***;
*** PROBLEMATIC IF PERSON_ID HAS MIN(DT) OCCUR MULTIPLE TIMES ***;
proc sql;
    create table try2 as
    select person_id,
        dt as index_dt format=datetime15.,  
        (dt + 365*24*60*60) as followup_date  format=datetime15.  
    from have
    group by person_id
    having dt=min(dt) 
;
quit;

3 个答案:

答案 0 :(得分:0)

尝试使用"选择不同的person_id"而不是"选择person_id" - 这应该有助于解决重复问题。我不确定SAS是否将365 * 24 * 3600视为每年正确的秒数,因此这也可能是一个影响因素。

答案 1 :(得分:0)

我不认为你只能在proc sql中做。我想以这种方式做到这一点:

*** GENERATE RANDOM DATES AFTER JAN 1, 2012 AND CREATE DATE/TIME VARIABLE ***;
data have ;
format date mmddyy10.  dt datetime15.;
do person_id=100, 200, 300, 400, 500;
do i = 1 to 100;
    jdate = int(1000 * ranuni(123987));
    date = mdy(1,1,2012) + jdate;
    dt = dhms(date, 0,0,0);
    output;
end;
end; 
run;

%macro do_elaboration(ds=);
/*count how many rows has my table */
%let dataset=&ds.;
%let DSID = %sysfunc(open(&dataset., IS));
%let nobs = %sysfunc(attrn(&DSID., NLOBS));
%let rc=%sysfunc(close(&DSID.));
/*loop over the number of rows*/
%do i=1 %to &nobs.;
    /*at each loop get one id*/
    data _NULL_;
       set &ds. (OBS=&i OBS=&i);
       call symputx("id", person_id);
    run;  
    /*with proc sql get the min_dt*/
    proc sql noprint;
       select min(dt) into:min_dt
       from &ds.
       where person_id=&id.
    ;
    quit;
    /*increment the min_dt with the function sas intnx*/
    data have_final_tmp;
        person_id = &id.;
        followup_date = intnx('dtyear',&min_dt,1);
        format followup_date datetime15.;
    run;
    /*put all id with the followup_date in only one dataset*/
    proc append base=have_final data=have_final_tmp force; 
    run;
%end;
%mend do_elaboration;
/*call the macro*/
%do_elaboration(ds=have);

我非常快速地编写代码并且我没有测试它所以你应该检查它,但概念很清楚。

答案 2 :(得分:0)

试试这个:

proc sql;
create table try1 as
select 
 min(dt) as index_dt  format=datetime15. ,
 calculated index_dt + 365*24*60*60 as followup_date format=datetime15.
from have
;
quit;

这里的诀窍是使用“计算”​​关键字。

此外,您可能需要执行以下操作来添加一年而不是乘法:

proc sql;
create table try1 as
select 
 min(dt) as index_dt  format=datetime15. ,
 input(compress(
  put(intnx('YEAR', datepart(calculated index_dt),1,'SAMEDAY'),date9.)||":"||
  put(timepart(calculated index_dt),time5.)),datetime15.) as followup_date format=datetime15.
from have
;
quit;