2007年3月18日日曜日

SASトレーニング「Data Integration Studio の活用」を受講してきました。



先日、開講されたSAS Institute Japan株式会社のSASトレーニングコース


「SAS Data Integration Studio の活用(3日間)」を受講してきました。




『SAS Data Integration Studio』とは、


SAS V9のBIツールのうちの1つで、GUIによるETLプロセスの開発・管理を可能にしたプロダクトです。


(『SAS ETL Studio』の後継プロダクトです。)



主な特徴として、



 ・データマートの設計及び作成


 ・OLAPキューブの構築


 ・各種レポートの作成


 ・SASストアドプロセスの作成


 ・データクレンジング


 ・各種ジョブのスケジューリング



といった作業を、全てGUIによる操作で実現できます。



特に、データマート作成とOLAPキューブ構築に関しては、


SASの製品紹介ページで謳われているとおり、


かなりの簡易化・効率化が期待できることを実感しました。




『SAS Data Integration Studio』に関する詳細は、


SAS9 Portal: SAS Data Integration Serverまたは、SAS | SAS Data Integration Studioを、



SASトレーニング「SAS Data Integration Studio の活用」に関する詳細は、


[Training:SAS Data Integration Studioの活用(旧:SAS ETL Studioの活用)]を、


ご覧下さい。




NIでは今後も、SAS V9の各種BIツールに関する知識・情報を積極的に吸収してく予定です。


2007年3月14日水曜日

V9での新機能「DCREATE関数」



decrement 」ではありません。


directory create


つまり、ディレクトリ(フォルダ)を作成するSASの関数です。



ディレクトリ(フォルダ)作成を、わざわざSASでやらなくてもという気もしますが、


せっかく加わった関数なので使ってみましょう。





以下のように、D:\tempの直下に「test」というフォルダがあります。


f:id:n-insight:20070313165611g:image


この「test」というフォルダ内に、DCREATE関数 でフォルダを作成してみます。



 data _NULL_ ;


  dir1 = "テストフォルダ1" ;


  rc = dcreate (dir1, 'd:\temp\test\') ;


 run ;



構文的には、DCREATE ( 第1引数 , 第2引数 )です。



第1引数には、作成するフォルダ名の文字列(文字変数)


第2引数には、フォルダを作成する場所をフルパスで与えます。



戻り値をVIEW TABLEで見てみると、何も入っていない(ブランク)ので、左辺は適当なSAS名で構いません。



実行結果のログです。


f:id:n-insight:20070313165628g:image



フォルダを作成した旨がログに特別出力されていないのが、少し気持ち悪いですが、


「テストフォルダ1」というフォルダは、正常に作成されています。


f:id:n-insight:20070313172012g:image



ちなみに、上記のような状態(D:\temp直下に「test」フォルダしか無い場合)で



 data _NULL_ ;


  dir1 = "テストフォルダ1" ;


  rc = dcreate (dir1, 'd:\temp\testXXX\') ;


 run ;



というように、存在しないフォルダを第2引数に指定しても、


f:id:n-insight:20070313172639g:image


ログには、ERRORもWARNINGも出力されません。(もちろん、フォルダも作成されません。)


やっぱり少し気持ち悪いですね。




実用的な使用例を考えてみました。



各プロジェクトをフォルダ分けして管理する場合に、


f:id:n-insight:20070313172928g:image


のようなSASデータセットを作成しておき、



 %Macro createDir( projectName ) ;


  data _NULL_ ;


   set temp ;


   * d:\tempの直下に基準となるフォルダを作成 ;


   if _N_ = 1 then rc = dcreate ("&projectName", "d:\temp\") ;


   * 基準としたフォルダの直下に各フォルダを作成 ;


   rc = dcreate (dir, "d:\temp\&projectName") ;


  run ;


 %Mend createDir ;


 options MPRINT ;


 %createDir( Project01 ) ;



のようなマクロを実行すると、


f:id:n-insight:20070313173337g:image


のようにフォルダ構成を作ることができます。






社内にUNIX-SASが無いので試すことができませんが、


UNIXではディレクトリ権限等があるので、注意して使う必要がありそうです。





訂正:2007/03/13


DCREATE関数の戻り値を格納する変数について


「戻り値をVIEW TABLEで見てみると、何も入っていない(ブランク)ので、左辺は適当なSAS名で構いません。」


と記載しましたが、誤りでした。



お詫びとともに訂正させていただきます。




正確には、以下3パターンで戻り値が変わります。



①フォルダ(ディレクトリ)が正常に作成された場合


②作成するフォルダ(ディレクトリ)が既存の場合


③第2引数で指定したフォルダ(ディレクトリ)が存在しない場合



①では、作成されたフォルダ(ディレクトリ)のフルパスが戻り値になります。


(例 d:\temp\test\テストフォルダ1)



②③では、戻り値がブランクになります。


2007年3月12日月曜日

V9での新機能「CALL SYMPUTXルーチン」



今回は、V9で仲間に加わったCALLルーチンを紹介します。


その名もCALL SYMPUTXルーチン です。



V8まででもCALL SYMPUTルーチン というものはありました。


(勿論、V9でも存在します。)



そのCALL SYMPUTルーチン を、もう少し便利にしたものが


CALL SYMPUTXルーチン です。



その違いは結果を見れば明らかなので、早速やってみましょう。




以下のようなプログラムを実行してみます。



 data _NULL_ ;


  x = 1 ;


  call symputx("macX", x) ;


 run ;



実行結果も見てみましょう。


f:id:n-insight:20070311143752g:image


パッと見は何てことはないですが、CALL SYMPUTルーチン との違いは分かりますか?



以下はCALL SYMPUTルーチン での実行結果です。


f:id:n-insight:20070311144223g:image



お気付きでしょうか?


ログの出力に若干の違いが生じます。



「NOTE: 以下の箇所で数値を文字値に変換しました。」というメッセージが


CALL SYMPUTXルーチン では出力されません。



SASは、数値から文字値(または文字値から数値)に変換が行われた場合、


ログにその旨を必ず出力します。



CALL SYMPUTルーチン での結果も間違いではありませんが、


多少の気持ち悪さを感じる場合は、


 call symput("macX", put(x,best.)) ; のように、


一度、変数Xを文字値に変換してから、マクロ変数MACXを定義するというやり方をしていました。



CALL SYMPUTXルーチン を使用すると、そのような処理をする必要がなくなります。





もう1つ違いを挙げておきます。


上記の結果から考えると、ある意味必然的なことですが・・・。



 data _NULL_ ;


  x = 1 ;


  y = 2 ;


  call symputx("macX", x) ;


  call symput("macY", y) ;


 run ;


 %put *****macX=&macX***** ;


 %put *****macY=&macY***** ;



のようなプログラムを実行すると、


%PUTステートメントでのログの出力結果に違いがでます。


f:id:n-insight:20070311152321g:image


お分かりですね?



CALL SYMPUTルーチン で数値をそのままマクロ変数に定義すると、


左にブランクが入った状態でマクロ変数に値が格納されます。



よって、


f:id:n-insight:20070311153235g:image


のような結果になるわけです。




以上2点。


CALL SYMPUTルーチン との違いにクローズアップして、CALL SYMPUTXルーチン を紹介しました。


2007年3月9日金曜日

V9での新機能「CAT/CATS/CATT/CATX関数」



これまた便利な関数が仲間入りしました。



いわゆる文字列結合をした結果を返すCAT関数です。


CATS/CATT/CATX関数も同じ仲間ですが、動作に少し違いが出ます。


詳しくは下記で説明していきます。)




V8までですと、文字列結合する場合は



 var1 = "ABC" || "DEF" ;



のように、"||"で文字列(文字変数)同士を結合していました。


(ちなみに、"!!"でも記述できました。かなりマニアック?)





V9でCAT(CATS/CATT/CATX)関数を使うと以下のように記述できます。



 data _NULL_ ;


  x = "NI " ; * Iの後にブランク ;


  y = " Nature Insight " ; * Nの前にブランク、tの後にブランク ;


  z = " Co.,Ltd. " ; * Cの前にブランク、d.の後にブランク ;


  z1 = cat (x, y, z) ;


  z2 = cats(x, y, z) ;


  z3 = catt(x, y, z) ;


  z4 = catx("_", x, y, z) ;


  put z1 = ;


  put z2 = ;


  put z3 = ;


  put z4 = ;


 run ;




先に、実行結果を見てみます。


 f:id:n-insight:20070308182526g:image


関数の戻り値の格納先の変数(z1~z4)には、文字変数を結合した値が入っていますね。


(値は微妙に違っていますが)




では、1つずつ説明していきます。



・CAT関数


 引数で指定した文字列(文字変数)を単純に結合します。


・CATS関数


 引数で指定した文字列(文字変数)を、それぞれの最初と最後のブランクを取り除いて結合します。


・CATT関数


 引数で指定した文字列(文字変数)を、それぞれの最後のブランクのみを取り除いて結合します。


・CATX関数


 引数で指定した文字列(文字変数)を、それぞれの最初と最後のブランクを取り除き


 第1引数で指定したデリミタ(区切り文字)を付加して結合します。




ログからですと、少し分かりにくいかもしれませんが、


1つ1つを注意深くみると、上で説明した通りの結果が返ってきていることが分かります。


(文字列中のブランク("Nature Insight"ですとeとIの間のブランク)は取り除かれないようです。)





V8で実行すると、完全なシンタックスエラーになります。


 f:id:n-insight:20070308185127g:image






動きはさりげないですが、大量の文字列(文字変数)を結合するとき等は重宝しそうですね。


(var1 || var2 || var3 || var4 || var5 ||~のように"||"を沢山記述する必要がなくなるので)



ちなみに、CAT関数という名称は、おそらく「concatenate(連結させる)」から取ったものと思われます。


2007年3月8日木曜日

LENGTH関数あれこれ



文字通り、文字列の長さを返す関数です。



LENGTH (第1引数)



のように、文字列(文字変数)を引数で与えます。



では、文字列(文字変数)がブランクのときは、どのような結果を返すと思いますか?



以下のような場合です。



 data _NULL_ ;


  x = "A" ;


  y = "" ;


  len_x = length (x) ;


  len_y = length (y) ;


  put len_x = ;


  put len_y = ;


 run ;



V8以降ではこの結果は同じになります。


f:id:n-insight:20070312164038g:image


ブランクも1として数えられていますね。



実は、V6ではブランクは0として返してくれたそうです。


(V6の環境がないので結果をお見せることができませんが・・・)




そして、V9では(V8、V6と行ったり来たりですみません)、上記のような違いを区別してくれる関数が加わりました。


LENGTHN関数 です。



構文は至ってシンプルです。



LENGTHN (第1引数)



早速、実行してみましょう。



 data _NULL_ ;


  x = "A" ;


  y = "" ;


  len_x_n = lengthn (x) ;


  len_y_n = lengthn (y) ;


  put len_x_n = ;


  put len_y_n = ;


 run ;



f:id:n-insight:20070312171212g:image


ちゃんと、ブランクの場合に0が返ってきましたね。




ちなみに、LENGTHC関数 というのも加わりまして、


動きは下記のとおりです。



 data _NULL_ ;


  x = "A " ; * Aの後ろに半角スペースが3つ入っています ;


  len_x = length(x) ;


  len_x_c = lengthc(x) ;


  put len_x = ;


  put len_x_c = ;


 run ;



f:id:n-insight:20070312171505g:image


文字列(文字変数)の後続ブランクも含めた結果を返してくれるようです。




以上。LENGTH関数 とそれに関連したモノを紹介しました。


2007年3月6日火曜日

V9での新機能「COUNT/COUNTC関数」



V9で仲間に加わった関数を紹介します。


COUNT関数とCOUNTC関数です。



コレ結構使えそうです。



名称から想像つくかもしれませんが、


検索対象から検索値をカウントして、その結果(カウント数)を返す関数です。



今までですと、


SUBSTR関数で1文字ずつ切り出して、その桁数分処理を繰り返したり、


COMPRESS関数で検索値を取り除いた桁数と元の桁数から算出したりと、


やりたいことは単純明解なのに手間のかかる処理が必要でした。



それでは実際にやってみましょう。



まずは、COUNT関数です。



 * ① ;


 data _NULL_ ;


  x = "NI Nature Insight" ;


  y = count(x, "NI") ;


  put y = ;


 run ;



結果は以下の通りです。


f:id:n-insight:20070305223604g:image


変数Xの"NI Nature Insight"


赤字部分が検索に引っ掛かり、1という戻り値が返ってきました。



変数Xの"NI Nature Insight"


青字部分もカウントしたい場合は、COUNTC関数を使います。



 * ② ;


 data _NULL_ ;


  x = "NI Nature Insight" ;


  y = countc(x, "NI") ;


  put y = ;


 run ;



f:id:n-insight:20070305224331g:image


変数Xの"NI Nature Insight"


赤字部分が検索に引っ掛かり、4という戻り値が返ってきました。



①と②の違いは分かりましたか?


①(COUNT関数)は、第2引数を文字列として検索するのに対して、


②(COUNTC関数)は、第2引数を文字として検索します。




②の結果からも分かるように、上記のような書き方ですと


いわゆる大文字小文字を別のモノとして検索しているのが分かります。


(②で"NI Nature Insight"の青字部分が検索結果にカウントされていません。)




以下のように、第3引数を与えると、大文字小文字を区別しない検索結果が返ります。



 * ③ ;


 data _NULL_ ;


  x = "NI Nature Insight" ;


  y = count(x, "ni", "i") ;


  put y = ;


 run ;



f:id:n-insight:20070305224348g:image



 * ④ ;


 data _NULL_ ;


  x = "NI Nature Insight" ;


  y = countc(x, "ni", "i") ;


  put y = ;


 run ;



f:id:n-insight:20070305224402g:image



③の結果はともかく、④の結果をよく見て下さい。



変数Xの"NI Nature Insight"赤字部分が全て検索結果にカウントされて、


戻り値として、6が返ってきます。





第3引数に与えるキーワードとして、他に"t"、"o"、"v"があるようです。


(COUNT関数は、"i"、"t"のみ)


※詳しくは、sas.com内のWhat’s New in the Base SAS 9.0, 9.1, and 9.1.3 Languageをご覧下さい。


2007年3月1日木曜日

書籍購入『DB Magazine 2007年04月号』『日経ソフトウエア 2007年04月号』


SORTプロシジャのV9での拡張




V9から拡張されたSORTプロシジャのオプションを紹介します。




下記のようなSASデータセット『temp.sas7bdat』があるとします。


 f:id:n-insight:20070228141232g:image



このデータを変数「key1」でユニークにする場合、



 * ①元のデータを残す場合 ;


 proc sort data = temp out = temp2 nodupkeys ;


  by key1 ;


 run ;



 * ②元のデータから重複レコードを削除する場合 ;


 proc sort data = temp nodupkeys ;


  by key1 ;


 run ;



のような記述になるかと思います。


出力イメージは


 f:id:n-insight:20070228141259g:image


な感じですね。



では、重複削除されたレコードだけのデータを作る場合はどうでしょうか。


出力イメージは


 f:id:n-insight:20070228141321g:image


な感じです。



今までですと、変数「key1」でSORTをした後で、



 data temp_dup ;


  set temp ;


  by key1 ;


  if ^first.key1 and ^last.key1 ;


 run ;



な感じで記述するのが一般的な手法です。




これを、V9で拡張されたオプション「DUPOUT=」を使うと以下のように記述できます。



 proc sort data = temp dupout = temp_dup nodupkeys ;


  by key1 ;


 run ;



実行結果のログは以下の通りです。


 f:id:n-insight:20070228182829g:image


7OBSのデータが、3OBSと4OBSのデータに分かれて出力されます。



もしも、入力元のデータ(この場合は「temp.sas7bdat」)をそのまま残したければ



 proc sort data = temp out = temp_uniq dupout = temp_dup nodupkeys ;


  by key1 ;


 run ;



のように、「OUT=」オプションも併記します。


 f:id:n-insight:20070228183801g:image





ちなみに、V8で同じ記述で実行すると


 f:id:n-insight:20070228190258g:image


のように、完全なシンタックスエラーになります。





利用できるシチュエーションをいろいろと模索してみましたが、


ん~、デバッグ作業ぐらいですかね。



任意のキーでユニークの状態が前提のデータを対象に処理をかけてみて、


重複レコードがあった場合に、その内容が可視化できるといったような…。




いずれにせよ、知識として覚えておいて損はないと思いますので、


利用機会があれば試してみて下さい。


ネイチャーインサイト サイトリニューアル&NIBLOGの引っ越し

ご連絡が遅くなりましたが、 ネイチャーインサイトの際とがリニューアルしました。 https://www.n-insight.co.jp/ それに伴い、NIBLOGも引っ越しすることになりました。 https://www.n-insight.co.jp/niblog/ ...