LoginSignup
0
2

More than 3 years have passed since last update.

【SAS】CSVファイルの各行の文字列を一致検索条件として判定ループさせる

Last updated at Posted at 2020-05-30

目次

  1. 前提
  2. 目的
  3. 方法
  4. 参考
  5. 所感

前提

  • 実行環境

    • Windows10
    • Base SAS 9.4
  • 必要な知識

    • SASコードの文法
      • DATAステップSETステートメントによるSDS作成
      • ATRRIBステートメントによる列定義
      • INFILEステートメントによる外部ファイル読み込み
      • SETステートメントのnobsオプションによる行数取得
      • SELECTステートメントによる条件分岐
      • index()による文字列検索
      • MACRO,MACRO変数の定義、呼び出し
      • %DO %TO %ENDによるループ

目的

次のようなPV(Page View)LogがSDS(SAS Data Set)で存在するとき、

pvlog.sas7bdat
ID url
AAA https://abcde.news/category
AAA https://abcde.topics
BBB https://fghij/business/?cid=info
CCC https://https://klmno.weather/Japan/Tokyo
DDD https://https://klmno.tenki/world
EEE https://https://pqrst/pollen?bid=forecast

次のような表形式のcsvファイルを用いて、

page_ctgr_list.CSV
検索方法 検索文字列 カテゴリ
部分一致 https://abcde.news ニュース
完全一致 https://fghij/business/?cid=info ニュース
部分一致 https://klmno.weather 天気
完全一致 https://pqrst/pollen?bid=forecast 天気

以下のようにカテゴリを付与する。

pvlog_ctgr.sas7bdat
ID url カテゴリ
AAA https://abcde.news/category ニュース
AAA https://abcde.topics
BBB https://fghij/business/?cid=info ニュース
CCC https://https://klmno.weather/Japan/Tokyo 天気
DDD https://https://klmno.tenki/world
EEE https://https://pqrst/pollen?bid=forecast 天気

方法

  • 処理手順概要

    1. page_ctgr.csvをSDS化して、1行目から順に各列値をマクロ変数に保存
      (n行*m列のとき、n*m個のマクロ変数ができる)。
    2. pvlog.sas7bdatの各urlに対して、page_ctgr.csvの検索文字と検索方法で1行目から順に判定。
    3. 検索一致した行のカテゴリを付与。1つも一致しなければ欠損にする。
  • 実装したSASコード

* 入出力フォルダ指定(任意);
libname I_DIR = "/project/input/" access = readonly
libname O_DIR = "/project/output/"

* ページカテゴリ取得マクロ定義;
%MACRO GetPageCtgr(INPUT_DIR=
                  ,I_SDS_NM=
                  ,INFILE_NM=
                  ,OUTPUT_DIR=
                  ,O_SDS_NM=
);

* csvを読み込みSDSに変換;
data work.page_ctgr_list;
  attrib
    search_type   length = $8.   label = "検索方法"
    search_string length = $500. label = "検索文字列"
    page_ctgr     length = $8.   label = "ページカテゴリ"
  ;
  infile "&INPUT_DIR.&INFILE_NM."
    dlm = ","
    firstobs = 2
    dsd
    missover
  ;
  input search_type search_string page_ctgr;
run;

* page_ctgr_listの行数および1行目から順に各列値をマクロ変数に保存;
data _null_;
    set  work.page_ctgr_list end = eof;
    if  eof then call symputx("PAGE_CTGR_LIST_OBS_CNT", _N_);
    call symputx(cats("SEARCH_TYPE", _N_)  , search_type);
    call symputx(cats("SEARCH_STRING", _N_), search_string);
    call symputx(cats("PAGE_CTGR",_N_)     , page_ctgr);
run;

* pvlogのurlに対応するページカテゴリを付与する;
data &OUTPUT_DIR.&O_SDS_NM.;
  set &INPUT_DIR.&I_SDS_NM.;

  * 検索方法は部分一致と完全一致の2種類のみであるのは既知とし、部分一致を先に判定する;
  * 1つも一致しないときは何もしない=ページカテゴリは欠損になる;
  select;
    %DO I = 1 %TO &PAGE_CTGR_LIST_OBS_CNT.;
      %IF &&SEARCH_TYPE&I.. = 部分一致 %THEN %DO;
        when(index(url, "&&SEARCH_STRING&I..")) page_ctgr = "&&PAGE_CTGR&I..";
      %END
      %IF &&SEARCH_TYPE&I.. = 完全一致 %THEN %DO;
        when(url = "&&SEARCH_STRING&I..")) page_ctgr = "&&PAGE_CTGR&I..";
      %END
    %END;
    otherwise;
  end;
run;

%MEND GetPageCtgr;

* マクロ実行;
%GetPageCtgr(INPUT_DIR  = I_DIR
            ,I_SDS_NM   = pvlog
            ,INFILE_NM  = page_ctgr_list.csv
            ,OUTPUT_DIR = O_DIR
            ,O_SDS_NM   = pvlog_ctgr
);

参考

* page_ctgr_listの行数をマクロ変数に保存;
data _NULL_;
  set work.page_ctgr_list nobs = page_ctgr_list_obs_cnt;
  call symputx("PAGE_CTGR_LIST_OBS_CNT", page_ctgr_list_obs_cnt)
run;

* page_ctgr_listの1行目から順に各列値をマクロ変数に保存;
data _NULL_;
  set work.page_ctgr_list;
  %DO I = 1 %TO &PAGE_CTGR_LIST_OBS_CNT.
    if _N_ = &I. then do;
      call symputx("SEARCH_TYPE&I."  , search_type);
      call symputx("SEARCH_STRING&I.", search_string);
      call symputx("PAGE_CTGR&I."    , page_ctgr);
    end;
  %END;
run;
  • 検索方法やページカテゴリ別にcsvファイルを分けて管理したいとき、
    一連の処理をファイル数だけループさせると再現が可能。
    ファイル名(文字列)リストでループを回すとき、以下が参考になる。
    https://y-mattu.hatenablog.com/entry/2016/08/05/010801

所感

  • この処理を作った理由は、カテゴリリストの変更があるたびに条件式を書き換える作業を避けるためです。
  • 現在Pysparkを使うようになったため、同様の処理をPysparkで実装する内容を投稿する予定です。
  • QiitaのSASシンタックスハイライトではマクロ変数に色付けてくれないんですね。
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2