フリーテキストから日付を取り出す② 複数出現した分だけオブザベーションに起こすパターン

昔、アルバイトしていた時に、シフト表組んでたことがあったのですが、バイトメンバーがそれぞれ出勤できない日をメールで送ってきてそれをスケジュール帳に書き起こして、とても面倒でした。

データセットにすると以下のような感じです。

data Q1;
length NAME $10. COMMENT $100.;
NAME='Aさん';COMMENT='2014/01/02と2014/01/03は休みたいです';output;
NAME='Bさん';COMMENT='無理な日、2014/01/01,2014/01/03,2014/01/04';output;
NAME='Cさん';COMMENT='予定があるので2014/01/07はでれません';output;
run;






さてこれを











のような形にするにはどうしましょうか?

前回の例では、1データに1回しか日付が含まれていないという強力な前提条件がありましたが
今回は違います。
データを受取るまで、その人によって無理な日が何日あるかもわかりません。

さて、そういったパターン出現数が可変、不明である場合に全てのパターンを抽出したい時は
call prxnextルーチンとsubstrtのコンボが有効であったりします。

先にコードから

data A1;
set Q1;
   ID=prxparse("/\d{4}\/\d{1,2}\/\d{1,2}/");
   START=1;
   STOP=length(COMMENT);
   call prxnext(ID, START,STOP,COMMENT,POSITION,LENGTH);
      do while (POSITION>0);
         YASUMI=substr(COMMENT,POSITION,LENGTH);
   output;
         call prxnext(ID, START,STOP,COMMENT,POSITION,LENGTH);
      end;
run;

結果は






です。

変数NAME YASUMIだけをkeepすれば目的とするデータセットと同じになります。

call prxnextルーチンは第一引数にprxparse関数で定義した正規パターン、第2引数はパターンマッチングを開始する位置を指定しておくと、マッチする部分があったらその終了位置に更新されます(正確にいうとPOSITION + MAX(1,LENGTH)の値)。第3引数はパターンマッチする終点位置、第4引数に対象とする変数、第5引数はパターンマッチでマッチした場合の開始位置が入ります、そして第6引数にマッチした部分の長さが入ります。

do while (POSITION>0);としているのは、call prxnextルーチンの特性として、順次、次にマッチする部分を情報を返してくれるということと、マッチする箇所がある限りPOSITIONは数字を返すということから成立するループです。

YASUMI=substr(COMMENT,POSITION,LENGTH);

は一致する開始する位置から、一致した部分の長さ分を抜き出せばいいでしょっていうシンプルな発想ですね。







0 件のコメント:

コメントを投稿