ラベル インフォーマット: E8601DT の投稿を表示しています。 すべての投稿を表示
ラベル インフォーマット: E8601DT の投稿を表示しています。 すべての投稿を表示

2018年7月4日水曜日

【SAS9.3以前のBug】E8601DTインフォーマットで正しく変換できないことがある。



今回の記事はSAS9.3以前で発生するバグの話です。
(9.4では解消されてます)


CDISC対応でADaMのデータセットをよく作る方なら既にご存知かもしれません。
SAS社の Problem Note にE8601DTインフォーマットのバグについての記載があります。

Problem Note 43743: E8601DT informat might read beyond its intended boundary
http://support.sas.com/kb/43/743.html



再現してみましょう。


data TEST;
    length X1 X2 $16.;
    X1 = "2018-01-01T10:00";
    X2 = ":15";

    format Y e8601dt.;
    Y  = input( X1, e8601dt. );
run;

SAS9.4での実行結果
  X1 
  X2  
  Y  
 2018-01-01T10:00  :15  2018-01-01T10:00:00 


SAS9.3での実行結果(Bug)
  X1 
  X2  
  Y  
 2018-01-01T10:00  :15  2018-01-01T10:00:15 


9.3で実行すると、X1とX2が合体した日時がYに格納されてしまいました。



内部の動きとして、E8601DTインフォーマットはデフォルトで入力データから19文字読み込もうとします。
しかしX1はlengthが16しかないので、残りの3文字をX2から読み込んできちゃうという暴挙にでるわけです。


解決策
このバグが解消されているSAS9.4で実行するのが手っ取り早いです。

9.3なら、変換する変数のlengthを16じゃなくて19に設定しとくとか、
または以下のような感じでINPUT関数で変換する時に、後ろに半角スペースを3文字分くっつけて、無理矢理19文字にするっていうのはどうでしょうか。これらは検証してないんでうまくいくかは保証できないです。

  if X1 ^="" then Y  = input( X1 || "   ", e8601dt. );


よーわからんですね。気をつけましょう。


2017年10月5日木曜日

【CDISC】変数 [--DTC] から、ADTM, ADT, ATM への変換



CDISC関連の話。


変数「--DTC」を、ADaM変数「ADTM」「ADT」「ATM」に変換するときの、ISO8601のフォーマットと書き方を載せときます。




[--DTC] が日付のみ (時刻を含まない) の場合


※以下の例は「2017」「2017-10」等の、日付が揃っていないデータは想定していません

data DT1;

    LBDTC = "2017-10-03";

    ADT    =  input( LBDTC, e8601da. );

run;





[--DTC] が日時の場合


※以下は想定していません。
・日時が揃っていないデータ(「2017-10-03」「2017-10-03T09」等)
・秒の小数部分が含まれているデータ(「2017-10-03T09:10:12.345」等)

※以下リンクの記事に紹介してるバグにも注意。
【SAS9.3以前のBug】E8601DTインフォーマットで正しく変換できないことがある。


data DT1;

    LBDTC = "2017-10-03T09:10:00";

    ADTM =  input( LBDTC, e8601dt. );
    ADT    =  input( LBDTC, e8601da. );
    ATM    =  timepart( input( LBDTC, e8601dt. ) );

run;

・ATMだけいったん日時変換してから、TIMEPART関数で時刻部分をとりだしています。




以上、自分用のメモ記事でした。