sas proc sql-获取最小日期并添加1年
我有一个ID为的数据集,每个ID都有多个日期(实际上是datetime)。我想使用procsql来获取最短的日期时间,并将最短的日期时间增加1年。我试图在一个procsql中完成这一切,但一直在摸索,无法让它工作。下面是两次尝试。如有任何建议,我将不胜感激sas proc sql-获取最小日期并添加1年,sas,proc-sql,Sas,Proc Sql,我有一个ID为的数据集,每个ID都有多个日期(实际上是datetime)。我想使用procsql来获取最短的日期时间,并将最短的日期时间增加1年。我试图在一个procsql中完成这一切,但一直在摸索,无法让它工作。下面是两次尝试。如有任何建议,我将不胜感激 *** GENERATE RANDOM DATES AFTER JAN 1, 2012 AND CREATE DATE/TIME VARIABLE ***; data have ; format date mmddyy10. dt
*** 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;
尝试使用“选择不同的人员id”而不是“选择人员id”-这将有助于解决您的重复问题。我不确定SAS是否将365*24*3600视为每年正确的秒数,因此这可能也是一个影响因素。尝试使用“选择不同的人员id”而不是“选择人员id”-这将有助于解决您的重复问题。我不确定SAS是否将365*24*3600视为每年正确的秒数,因此这也可能是一个促成因素。我认为您不能仅使用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);
我写代码很快,我没有测试它,所以你应该检查它,但概念很清楚。我认为你不能只在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);
我写代码很快,不进行测试,所以你应该检查一下,但概念很清楚。试试这个:
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;
试试这个:
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;
谢谢-我需要的是“经过计算”的声明!第二,感谢INTNX代码增加了一年。谢谢-我需要的是“计算”语句!再次感谢INTNX代码增加了一年。