2016-05-03 4 views
1

У меня есть набор данных с идентификаторами, и каждый ID имеет несколько дат (фактически datetime). Я хочу использовать PROC SQL для получения минимального времени и времени, а также добавить минимум 1 год. Я пытаюсь сделать все это в одном PROC SQL, но я не знаю, как это сделать. Ниже приведены две попытки. Буду признателен за любые советы.sas proc sql - получите мин. Дату и добавьте 1 год

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

ответ

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; 
+0

Благодарности - «рассчитанной» утверждение, что мне нужно! И второй Спасибо за код INTNX, чтобы добавить год. – SunnyRJ

0

Попробуйте использовать «select different person_id» вместо «select person_id» - это должно помочь с вашей проблемой с дубликатами. Я не уверен, что SAS обрабатывает 365 * 24 * 3600 как правильное количество секунд в год, так что это может быть и фактором, способствующим этому.

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

Я пишу код очень быстро, и я не проверить его, так что вы должны проверить это, но концепция ясна.

Смежные вопросы