ラベル VBA の投稿を表示しています。 すべての投稿を表示
ラベル VBA の投稿を表示しています。 すべての投稿を表示

EXCELを媒介にして、漢字をカタカナに無理やり直す方法

日本語は、やはり母国語なので言語としては愛着があるのですが、ことプログラムで処理するとなると、これほど厄介な言語って他にあんのかな?って気になってしまいます。

名寄せ処理する上で大問題なのが、日本語は、漢字・ひらがな・カタカナ(+数字や記号)が混在しているということです。

最近、受けた質問ですが、例えば以下の2つのデータセットがあったとします。

data Q1;
length TERM $10.;
 TERM='豆腐';output;
 TERM='アズキ';output;
 TERM='だいず';output;
run;







data Q2;
length TERM $10.;
 TERM='大豆';output;
 TERM='とうふ';output;
 TERM='小豆';output;
run;







これで、この2つのデータセットを同じ言葉同士でマージしてと言われたらどうしますか?

人の目であれば、「豆腐」と「とうふ」が同じ言葉であることは一目了然なのですが、これを機械に
わかってもらうのはとても大変です。

たとえば、これが漢字を含まない、ひらがなとカタカナだけのデータであれば
kpropcase関数で、いずれかに統一させてマージができます。

kpropcaseについては色々な方が説明されているので、そちらを見て下さい

【SAS忘備録】
http://sas-boubi.blogspot.jp/2013/12/blog-post_16.html

【SAS Utility】
http://sasutility.blogspot.jp/2010/07/blog-post.html

【SAS社Q&A】
http://www.sas.com/offices/asiapacific/japan/service/technical/faq/list/body/ba268.html


ところが、漢字の変換になると、SASだけでは(僕の知る限り)変換処理する機能がありません
(多分ですが、、、。もしあったなら教えてください)

なので何かしら外部アプリケーションの力を借りるしかないはずです。

SASの中でCやJAVAなんかのコードを利用できるらしいので、そっちを使うか或いは、
proc httpなどでweb上とやりくりができるので、yahooが提供している「かな漢字変換API」
http://developer.yahoo.co.jp/webapi/jlp/jim/v1/conversion.html
などにデータを送って、変換されたものを受取るということもできるはずです。


しかし、いずれの方法をとるにせよ、SASとは別の知識が要求されるので、他の言語ができないと結構ハードルは高くなります。


そこで、まだちょっとは馴染みのあるEXCELさんに奴隷のように働いて貰いましょう。
EXCEL VBAも別の言語ですが、まぁまだ簡単でしょう。

ちなみに、これから紹介する方法は、もはやプログラミングではない!って感じの乱暴なものですのであしからず。


まず、適当な名前でマクロ付のexcelファイル(xlsm)を作成します。
ここではCドライブ直下に、BOOK1.xslmという名前でつくっています。

そして標準モジュールに

Function getphonetic(a)
getphonetic = Application.getphonetic(a)
End Function












と書いて、ユーザー定義関数を定義します。

このApplication.getphoneticは変換候補の一番目にくるカタカナを取得します。
なので、先に断っておきますが、必ずしも正しい読み仮名であるとは限りません。人名・地名や
読み方のたくさんある言葉、一般的ではない言葉の場合、思いどおりにいかないこともあります。

さて、関数が定義できれば

次にSheet1でいいので、1列目2列目を全選択して、名前を定義します。ここでは「AREA」としています。












さて、もう何をしようとしているか気付かれたと思いますが、ここで2列目の全セルに
「=GETPHONETIC(RC[-1])」という関数を入れます。








これによって1列目のセルに何か文字をいれたら、2列目でカタカナ変換された値がでてくる
作業シートができました。


あとはもうlibnameの世界ですね。

一気に全コードを載せます。

libname EX "C:\Book1.xlsm" header=no scantext=no;

data EX.'AREA'n;
 set Q1;
 modify EX.'AREA'n;
 F1=TERM;
run;

data _Q1;
length TERM1 KANA $10.;
 set EX.'AREA'n;
 where F1^='';
 TERM1=F1;
 KANA=F2;
keep TERM1 KANA;
run;

data EX.'AREA'n;
 set Q2;
 modify EX.'AREA'n;
 F1=TERM;
run;

data _Q2;
length TERM2 KANA $10.;
 set EX.'AREA'n;
 where F1^='';
 TERM2=F1;
 KANA=F2;
keep TERM2 KANA;
run;

proc sort data=_Q1;
 by KANA;
run;

proc sort data=_Q2;
 by KANA;
run;

data A1;
informat TERM1 TERM2; 
 merge _Q1 _Q2;
 by KANA;
run;


で結果のA1の中身は







というわけです。


ちなみに途中の_Q1の中身は








_Q2は







です。


さて、この方法はお手軽で、excelさえあればできますが、問題もあります。

まず、こういった名寄せ処理は扱うデータ数が巨大な場合が多いですが、この方法だと
excelシートの行の限界数までしかできませんし、変換のためだけに無駄にシートに読み書きして
いるので、もう馬鹿みたいに遅いです。重すぎて止まっちゃうかも。

また、普通にタイピングしていて変換して1番にくる文字を選ぶだけなので、データの文脈おかまいなしです。変換結果を目でチェックしたほうが無難です。

さて、悪口ばかり言いましたが、大した量でなくて、ちょっとくらいミスがあってもいいような名寄せならこれで充分実用に耐えうります。

来年の論文の一部にしようかな。










LIBNAMEとVBAで、EXCELとSASをつないで対話的アプリケーションにする

EXCELにはEXCEL VBAという便利な言語がくっついているので、これを使ってEXCELからSASを実行することができます。

またSASのLIBNAME EXCEL機能を使えば、EXCELの値を自由に読み込み&書き込みできます。

この二つを組み合わせれば、みんな大好きエクセルさんをインターフェースにして、そこに
ユーザーが入力した値をSASに渡して、処理を行い、処理結果をエクセルに返すことができます。


その簡単な例を紹介します。
今、「D:\FACE.xlsm」というマクロつきのエクセルブックがあったとします。
黄色の部分にそれぞれの計算結果が入れたいとします(黄色セルは表示形式:数値)












そして、「D:\計算.sas」というSASファイルがあり、
その中身は以下のコードだとします。

libname EXLIB "D:\FACE.xlsm" header=no scan_text=no;

data Q1;
 set EXLIB."Sheet1$D8:D8"n ;
 rename F1=X;
run;

data Q2;
 set EXLIB."Sheet1$F7:F7"n ;
 rename F1=Y;
run;

data Q3;
 set EXLIB."Sheet1$F9:F9"n ;
 rename F1=Z;
run;

data A1;
 set Q1;
 set Q2;
  A=X+Y;output;

  A=.;output;

 set Q1;
 set Q3;
  A=X+Z;output;
run;

data EXLIB."Sheet1$H7:H9"n ;
 set A1;
 modify EXLIB."Sheet1$H7:H9"n ;
  F1=A;
run;


何をしているかというとエクセル数字の入っている3セルを読み込んで
計算結果を黄色のセルに出力しているわけです。


で肝心のEXCELからSASを起動する方法ですが
「計算ボタン」に以下のコードを結び付けています。

Sub ボタン1_Click()
Dim sasobj As Object
Set sasobj = CreateObject("SAS.application")
sasobj.Visible = False
sasobj.Submit ("%inc 'D:\計算.sas';")
sasobj.Submit ("ENDSAS;")
End Sub

これだけです。
実行ログファイルが欲しい場合はprinttoプロシジャ等をいれましょう。


以上の準備が整えば、あとはエクセル上のボタンをクリックすれば











と一瞬で計算結果がエクセルに返ってきます。
endsasをいれているので、SASも勝手にとじます。


この一連の流れは結構使えると思います。


あと、これは勝手なお願いですが、LIBNAME EXCELは便利で、DDEにはない長所をいっぱい
持っているんですが、いまいちまだ解らない部分や、誰も試していない部分が多くて
DDEのように枯れた知識になってない感じがあります。

新しく発見された部分があれば、どんどん共有していけたらと思います。