我有大约30个数据集,每个数据集约有20个日期字段,其中变量类型在字符和数字之间以及日期和日期时间格式之间变化,即以下情况...
a。)数字 - 日期 b。)数字 - 日期时间 c。)字符 - 日期 d。)character - datetime
我想将每个字段转换为数字和date9。格式。我尝试编写下面的宏,当变量是一个字符串时,它不会产生正确的结果。出了什么问题? ...如果未正确指定字符变量dateformat,则sas似乎不能正确解释输入语句。
%macro converttodate(inlib,indata,outlib,outdata,invar,outvar);
ods listing close;
ods output dataset.variables = work.formats;
proc contents data = &inlib..&indata.;
run;
data work.formats;
set work.formats;
where lowcase(compress(variable)) = lowcase(compress("&invar."));
run;
data _NULL_;
set work.formats;
call symput('dtype',compress(lowcase(type)));
call symput('dformat',compress(lowcase(format)));
call symput('dlen',compress(put(len,8.)));
run;
%PUT INVAR = ** &invar. ** OUTVAR = ** &outvar. **;
%PUT TYPE = ** &dtype. **;
%PUT FORMAT = ** &dformat. **;
%PUT LENGTH = ** &dlen. **;
%if &dtype. = num %then %do;
data &outlib..&outdata.;
length tmp_put $50;
set &inlib..&indata.;
format &outvar. date9.;
tmp_put = compress(put(&invar.,&dformat.));
if index(tmp_put,':') > 0 then &outvar. = datepart(&invar.);
else &outvar. = &invar.;
drop tmp_put;
run;
%end;
%else %do;
data &outlib..&outdata.;
set &inlib..&indata.;
format &outvar. date9.;
if index(&invar.,':') > 0 then &outvar. = datepart(input(&invar.,datetime.));
else &outvar. = input(&invar.,date.);
run;
%end;
%mend;
E.g。
data work.test;
format x1 date9. y1 datetime30.6;
x1 = mdy(10,16,1922);
x2 = put(x1,date9.);
y1 = 100000;
y2 = put(y1,datetime30.6);
run;
%converttodate(
inlib = work,
indata = test,
outlib = work,
outdata = test,
invar = x2,
outvar = x2_out);
答案 0 :(得分:1)
宏中的这一行导致意外行为:
else &outvar. = input(&invar.,date.);
日期的默认长度。是7,因此它将日期读作16OCT19,即2019年
如果将其更改为date9,它将正常工作。如果要更改整个宏,可以查看inputn函数,其中函数的第二个参数可以通过输入数据的长度动态确定。
data &outlib..&outdata.;
set &inlib..&indata.;
format &outvar. date9.;
in_format=catt("date", &dlen.);
if index(&invar.,':') > 0 then &outvar. = datepart(input(&invar.,datetime.));
else &outvar. = inputn(&invar.,in_format);
run;
答案 1 :(得分:0)
如果我在输入语句中使用正确的字符串长度,则输出变量似乎变得正确。我在%else%do之后调整了代码;如下
%else %do;
data _NULL_;
set &inlib..&indata.;
if length(compress(&invar.)) > 1 then do;
call symput('dlen2',compress(put(length(compress(&invar.)),8.)));
call symput('colon',compress(put((index(&invar.,':') > 0),8.)));
stop;
end;
else do;
call symput('dlen2','0');
end;
run;
%if &dlen2. ^= 0 %then %do;
data &outlib..&outdata.;
set &inlib..&indata.;
format &outvar. date9.;
%if &colon. = 1 %then %do;
&outvar. = datepart(input(&invar.,datetime&dlen2..));
%end;
%else %do;
&outvar. = input(&invar.,date&dlen2..);
%end;
run;
%end;
%else %do;
%PUT NO VALID OBSERVATIONS;
%end;
%end;