目次
前提
実行環境
- Windows10
- Base SAS 9.4
必要な知識
- SASコードの文法
- DATAステップSETステートメントによるSDS作成
- ATRRIBステートメントによる列定義
- INFILEステートメントによる外部ファイル読み込み
- SETステートメントのnobsオプションによる行数取得
- SELECTステートメントによる条件分岐
- index()による文字列検索
- MACRO,MACRO変数の定義、呼び出し
- %DO %TO %ENDによるループ
- SASコードの文法
目的
次のようなPV(Page View)LogがSDS(SAS Data Set)で存在するとき、
pvlog.sas7bdat
次のような表形式のcsvファイルを用いて、
page_ctgr_list.CSV
検索方法 | 検索文字列 | カテゴリ |
---|---|---|
部分一致 | https://abcde.news | ニュース |
完全一致 | https://fghij/business/?cid=info | ニュース |
部分一致 | https://klmno.weather | 天気 |
完全一致 | https://pqrst/pollen?bid=forecast | 天気 |
以下のようにカテゴリを付与する。
pvlog_ctgr.sas7bdat
方法
処理手順概要
- page_ctgr.csvをSDS化して、1行目から順に各列値をマクロ変数に保存
(n行*m列のとき、n*m個のマクロ変数ができる)。 - pvlog.sas7bdatの各urlに対して、page_ctgr.csvの検索文字と検索方法で1行目から順に判定。
- 検索一致した行のカテゴリを付与。1つも一致しなければ欠損にする。
- page_ctgr.csvをSDS化して、1行目から順に各列値をマクロ変数に保存
実装したSASコード
* 入出力フォルダ指定(任意);libnameI_DIR="/project/input/"access=readonlylibnameO_DIR="/project/output/"* ページカテゴリ取得マクロ定義;%MACROGetPageCtgr(INPUT_DIR=,I_SDS_NM=,INFILE_NM=,OUTPUT_DIR=,O_SDS_NM=);* csvを読み込みSDSに変換;datawork.page_ctgr_list;attribsearch_typelength=$8.label="検索方法"search_stringlength=$500.label="検索文字列"page_ctgrlength=$8.label="ページカテゴリ";infile"&INPUT_DIR.&INFILE_NM."dlm=","firstobs=2dsdmissover;inputsearch_typesearch_stringpage_ctgr;run;* page_ctgr_listの行数および1行目から順に各列値をマクロ変数に保存;data_null_;setwork.page_ctgr_listend=eof;ifeofthencallsymputx("PAGE_CTGR_LIST_OBS_CNT",_N_);callsymputx(cats("SEARCH_TYPE",_N_),search_type);callsymputx(cats("SEARCH_STRING",_N_),search_string);callsymputx(cats("PAGE_CTGR",_N_),page_ctgr);run;* pvlogのurlに対応するページカテゴリを付与する;data&OUTPUT_DIR.&O_SDS_NM.;set&INPUT_DIR.&I_SDS_NM.;* 検索方法は部分一致と完全一致の2種類のみであるのは既知とし、部分一致を先に判定する;*1つも一致しないときは何もしない=ページカテゴリは欠損になる;
select;%DOI=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;%MENDGetPageCtgr;* マクロ実行;%GetPageCtgr(INPUT_DIR=I_DIR,I_SDS_NM=pvlog,INFILE_NM=page_ctgr_list.csv,OUTPUT_DIR=O_DIR,O_SDS_NM=pvlog_ctgr);
参考
- https://sas-boubi.blogspot.com/2014/09/call-symputx.html
このページを見る前は行数と列値のマクロ変数保存を2ステップに分けて次のように実行していた。
* page_ctgr_listの行数をマクロ変数に保存;data_NULL_;setwork.page_ctgr_listnobs=page_ctgr_list_obs_cnt;callsymputx("PAGE_CTGR_LIST_OBS_CNT",page_ctgr_list_obs_cnt)run;* page_ctgr_listの1行目から順に各列値をマクロ変数に保存;data_NULL_;setwork.page_ctgr_list;%DOI=1%TO&PAGE_CTGR_LIST_OBS_CNT.if_N_=&I.thendo;callsymputx("SEARCH_TYPE&I.",search_type);callsymputx("SEARCH_STRING&I.",search_string);callsymputx("PAGE_CTGR&I.",page_ctgr);end;%END;run;
- 検索方法やページカテゴリ別にcsvファイルを分けて管理したいとき、
一連の処理をファイル数だけループさせると再現が可能。
ファイル名(文字列)リストでループを回すとき、以下が参考になる。
https://y-mattu.hatenablog.com/entry/2016/08/05/010801
所感
- この処理を作った理由は、カテゴリリストの変更があるたびに条件式を書き換える作業を避けるためです。
- 現在Pysparkを使うようになったため、同様の処理をPysparkで実装する内容を投稿する予定です。
- QiitaのSASシンタックスハイライトではマクロ変数に色付けてくれないんですね。