我有一个带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;
答案 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;