2014-12-22 12 views
0

我有中的每一個大約20日期字段30的數據集,其中所述可變型字符和數字之間之間以及日期和日期時間格式,即在下列情況下發生變化。 ..轉換字符變量到數字日期

一)數字 - 日期 二)數字 - 日期時間 C)字符。 - 日期 d)字符 - 日期時間

我想每一個人領域的數字和date9轉換。格式。我試着寫了下面的宏不產生正確的結果時,這個變量是一個字符串。出了什麼問題? ... 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; 

例如,

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

一些樣品投入? – usr2564301

+0

如果你運行上面的代碼x2_out將成爲代替「16OCT1922」 16OCT2019「。 – user1568780

回答

1

這條線在宏導致意外的行爲:

else &outvar. = input(&invar.,date.); 

日期默認長度。是7,所以如果你改變它date9它會正常工作,它讀取日期16OCT19,即2019年

http://support.sas.com/documentation/cdl/en/etsug/60372/HTML/default/viewer.htm#etsug_intervals_sect008.htm

。如果你想改變你的整個宏,你可以看看那裏給函數的第二個參數可以通過輸入數據的長度來動態確定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; 
0

如果我在輸入語句中使用正確的字符串長度,輸出變量似乎變得正確。我在%else%之後調整了代碼;如下

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