dlgcdir関数を使えば現在の作業ディレクトリが変更できます.
正しく実行できると戻り値は0になります.
415 /*現在の作業ディレクトリをlogに表示*/
416 data _null_;
417 rc=dlgcdir(); /*()を空にして実行すると現在のディレクトリを表示する*/
418 put rc=; /*正しく実行できているかの確認_別に不要ではあるが見るのには便利*/
419 run;
NOTE: 現在の作業ディレクトリは"piyopiyo"です。
rc=0 /*正しく実行できているので戻り値が0*/
NOTE: DATAステートメント処理(合計処理時間):
処理時間 0.00 秒
CPU時間 0.00 秒
420
421 /*現在の作業ディレクトリをhogeに変更*/
422 data _null_ ;
423 rc = dlgcdir("hoge") ; /*()に指定したフォルダを現在のディレクトリとする*/
424 put rc= ;
425 run ;
NOTE: 現在の作業ディレクトリは"hoge"です。
rc=0
NOTE: DATAステートメント処理(合計処理時間):
処理時間 0.00 秒
CPU時間 0.00 秒
現在のディレクトリを変更することで,指定したフォルダ内のプログラムを%incで読み込む際にファイル名の指定だけで済むので記述が短くなって良いですね.もちろん現在のディレクトリを変更しているので,何が指定したフォルダに出力されるかを確認する必要はありますが.
例えば指定したフォルダの中のhoge.sasとhoge2.sasを実行するには%incにファイル名を書くだけでokになります.もちろん実行するプログラムの前にフォルダパスを記載すれば指定していないフォルダのプログラムも実行できますが,タラタラ前に書くのがめんどくさい時もありますし,フォルダパスをマクロ変数に格納して何かのはずみでマクロ変数の上書きが意図せず起きたりするのが結構ややこしい印象です.
%inc "hoge.sas" ;
%inc "hoge2.sas" ;
私は使ったことないですけど便利そうですよね,そのうち使うかもしれません.
後はファイルメニューの「プログラムを開く」で,最初に表示されるファイルの場所が現在のディレクトリになれば最高なんですが…今はsasの保存場所かなんかが最初に出るんですよね…最初と言わずとも現在のディレクトリにすぐアクセスできればokなんですが.
2020年2月1日土曜日
2020年1月8日水曜日
sas studioが9.4M6に更新されてて嬉しい話
最近アクセスできなかったsas studioですが,先日復旧したようですね.
復旧したのでとりあえずproc product_statusを実行すると,BASE SASが9.4M6に更新されているじゃないですか.これで思う存分円グラフが試せるというもんです,やったぜ.円グラフの実用性については知りませんねえ…
復旧したのでとりあえずproc product_statusを実行すると,BASE SASが9.4M6に更新されているじゃないですか.これで思う存分円グラフが試せるというもんです,やったぜ.円グラフの実用性については知りませんねえ…
以下にせっかくなので実行したproc product_statusの結果を置いておきます.
毒にも薬にもなりませんが更新されててとてもうれしい.せっかくなので該当箇所を赤文字にしています.意味などないですが.
毒にも薬にもなりませんが更新されててとてもうれしい.せっかくなので該当箇所を赤文字にしています.意味などないですが.
この手の更新情報ってどこかで公開されたりとかってないですかね…私が知らないだけですか?
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
70
71 proc product_status ;
72 run ;
For Base SAS Software ...
Custom version information: 9.4_M6
Image version information: 9.04.01M6P110718
For SAS/STAT ...
Custom version information: 15.1
For SAS/GRAPH ...
Custom version information: 9.4_M6
For SAS/ETS ...
Custom version information: 15.1
For SAS/OR ...
Custom version information: 15.1
Image version information: 9.04.01M6P050819
For SAS/IML ...
Custom version information: 15.1
For SAS/QC ...
Custom version information: 15.1
For SAS/CONNECT ...
Custom version information: 9.4_M6
For SAS Enterprise Miner ...
Custom version information: 15.1
For SAS Time Series Workspace Macros ...
Custom version information: 15.1
Image version information: 9.04.01M5P110718
For SAS/ACCESS to Postgres ...
Custom version information: 9.4_M6
For SAS Integration Technologies ...
Custom version information: 9.4_M6
For SAS/Secure 168-bit ...
Custom version information: 9.41_M3
For SAS Credit Scoring ...
Custom version information: 15.1
For SAS Text Miner ...
Custom version information: 15.1
For SAS High-Performance Forecasting ...
Custom version information: 15.1
For High Performance Suite ...
Custom version information: 2.2_M7
For SAS Forecast Server Mid-Tier ...
Custom version information: 15.1
Image version information: 9.04.01M5P110718
For SAS/ACCESS Interface to PC Files ...
Custom version information: 9.4_M6
For SAS/ACCESS Interface to MySQL ...
Custom version information: 9.4_M6
2019年12月1日日曜日
htmlのタグを指定して値をsasデータセットに格納する話
sasでwebスクレイピングってあんまり事例がないと思うので紹介する話です.
スクレイピングしようとするとwebページをhttpプロシジャ使ってhtmlのタグ付きのテキストに変換して,そこから必要な分だけをデータセットに取り込むのがいいかなと記事投稿時点では考えています.
問題になるのが「必要な分だけデータセットに取り込む」の部分かと.vba等のほかの言語ならhtmlのclass名なりid名なりを指定して格納されている値を取れますが,タグ付きのテキストに変換しているのでそんな器用なことができません.所詮テキストです.かと言って取得時にhtmlのタグを使えないとお話にならないので,テキストは@を使えば読み込み箇所を動かせるのを利用して値を取得します.
例えば以下のようなタグ付きのテキストを仮に取得したとします.
今回欲しいのはその中でも「c-rating__val c-rating__val--strong list-rst__rating-val」classの値である「3.49」ですね.
<p class="c-rating c-rating--xl c-rating--val30 list-rst__rating-total cpy-total-score">
<i class="c-rating__star list-rst__rating-star">
</i>
<span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49
</span> </p>
<p class="list-rst__rvw-count is-highlight">
「3.49」を取るために以下の段階を踏みます.コードの全体は一番下にまとめてあります.
まずdlm="</"とすることで,sasの変数に</ごとに区切りを変えて値を取得できます.こうすることで上のテキストの緑の部分の前後は以下のようにsasデータセットに格納できます.1行が1obsに相当すると思ってください.
</i> <span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49
</span>
</p> <p class="list-rst__rvw-count is-highlight">
1つの変数に</i> <span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49と格納できたので,class="c-rating__val c-rating__val--strong list-rst__rating-val">が出てきたら読み込み位置を@で1つ進めて3.49を取得できます.
今回はclassタグを指定していますが,同じことをすればidタグも同様に指定して値が取れるはずです.と言うかidタグがユニークになるのでとれるならidの方がいいですね.
/*--コードの全体像*/
data OUT_P;
infile F_OUT dlm="</" dsd missover lrecl=30000 firstobs=1;
input @ 'class="c-rating__val c-rating__val--strong list-rst__rating-val">' V_VAL ;
/*--要らないレコードを削除*/
if V_VAL = . then delete ;
run;
/*--取得した値をデータセットに上書き ページ数分繰り返せばok*/
proc append base= V_OUT data= OUT_P ;
run ;
proc httpだとurlを指定するのでどうしてもテキストに変換するのは1ページごとになってしまいます.読み込みを複数ページにまたがってやりたい時はproc httpでページを読み込み→テキストをsasデータに変換→欲しい値をproc appendでデータに追加の3つをloopして行えばokと思います.ただし一気にwebページに複数回アクセスすると攻撃扱いされますので,loop内に適宜sleep関数を挟むのが必須です.
スクレイピングしようとするとwebページをhttpプロシジャ使ってhtmlのタグ付きのテキストに変換して,そこから必要な分だけをデータセットに取り込むのがいいかなと記事投稿時点では考えています.
問題になるのが「必要な分だけデータセットに取り込む」の部分かと.vba等のほかの言語ならhtmlのclass名なりid名なりを指定して格納されている値を取れますが,タグ付きのテキストに変換しているのでそんな器用なことができません.所詮テキストです.かと言って取得時にhtmlのタグを使えないとお話にならないので,テキストは@を使えば読み込み箇所を動かせるのを利用して値を取得します.
例えば以下のようなタグ付きのテキストを仮に取得したとします.
今回欲しいのはその中でも「c-rating__val c-rating__val--strong list-rst__rating-val」classの値である「3.49」ですね.
<p class="c-rating c-rating--xl c-rating--val30 list-rst__rating-total cpy-total-score">
<i class="c-rating__star list-rst__rating-star">
</i>
<span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49
</span> </p>
<p class="list-rst__rvw-count is-highlight">
「3.49」を取るために以下の段階を踏みます.コードの全体は一番下にまとめてあります.
まずdlm="</"とすることで,sasの変数に</ごとに区切りを変えて値を取得できます.こうすることで上のテキストの緑の部分の前後は以下のようにsasデータセットに格納できます.1行が1obsに相当すると思ってください.
</i> <span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49
</span>
</p> <p class="list-rst__rvw-count is-highlight">
1つの変数に</i> <span class="c-rating__val c-rating__val--strong list-rst__rating-val">3.49と格納できたので,class="c-rating__val c-rating__val--strong list-rst__rating-val">が出てきたら読み込み位置を@で1つ進めて3.49を取得できます.
今回はclassタグを指定していますが,同じことをすればidタグも同様に指定して値が取れるはずです.と言うかidタグがユニークになるのでとれるならidの方がいいですね.
/*--コードの全体像*/
data OUT_P;
infile F_OUT dlm="</" dsd missover lrecl=30000 firstobs=1;
input @ 'class="c-rating__val c-rating__val--strong list-rst__rating-val">' V_VAL ;
/*--要らないレコードを削除*/
if V_VAL = . then delete ;
run;
/*--取得した値をデータセットに上書き ページ数分繰り返せばok*/
proc append base= V_OUT data= OUT_P ;
run ;
proc httpだとurlを指定するのでどうしてもテキストに変換するのは1ページごとになってしまいます.読み込みを複数ページにまたがってやりたい時はproc httpでページを読み込み→テキストをsasデータに変換→欲しい値をproc appendでデータに追加の3つをloopして行えばokと思います.ただし一気にwebページに複数回アクセスすると攻撃扱いされますので,loop内に適宜sleep関数を挟むのが必須です.
2019年11月1日金曜日
話題の食べログの話
食べログの星が3.6と3.8の間に壁がある話を聞いたので,試しにサクッとグラフにした話です.スクレイピングで星を取得してヒストグラム書いてみました.なかなか普段スクレイピングなんてやらないのでだいぶ苦戦しましたがまあ何とか形にはなりました.以下のグラフ見てもらえればわかりますが,私がやった感じだとあんまり壁みたいなのはなかった気がします.下のグラフはx軸は星数,y軸が件数ですね.軸の設定がめんどくさかったのでラベルがV_VALになっていますが,そこに各店舗の星の数が格納されています.
今回は京都のお店を対象にしています.大阪と東京では既にグラフがありますので…
data V_ANNO ;
%SGTEXT(label="↓3.6", x1=3.6, y1=215, drawspace="DATAVALUE") ;
%SGTEXT(label="↓3.8", x1=3.8, y1=27 , drawspace="DATAVALUE", anchor="left") ;
run ;
title "京都のお店1200件 口コミ数順" ;
proc sgplot data=V_OUT sganno=V_ANNO ;
histogram V_VAL / scale=count nbins=40;
xaxis grid
values=(3.0 to 5.0 by 0.2)
offsetmin=0.05
offsetmax=0.05
;
yaxis offsetmax=0.05 ;
run ;
今回は京都のお店を対象にしています.大阪と東京では既にグラフがありますので…
星3.6と3.8で数に大きな差はありますが,グラフはそこまで不自然な形はしてない気がします.もちろんこんなものはデータの抽出の仕方次第でいくらでも結果を変えれるので,これだけを見て食べログがどうとかこうとか言うつもりはありません.特に今回は食べログの口コミ数順に上位1200件を取ってきただけです.どの順番でデータを取るかにもよりますしね.
スクレイピングの方法をありのままに書くことはちょっとよろしくない気がするのであんまり書きませんが,proc httpでwebページをテキスト化して取得→要る部分だけデータセット化→sgplotでヒストグラムです.sgplotのヒストグラムとtextステートメントが同時に使えなかったので,グラフ内の3.6とかの文字列はsgannoでやっていますがたぶん他に手はあると思います.
/*
以下が実際にグラフを書いた時のプログラムです
V_OUTに星の数が,V_ANNOにグラフ内の文字列が入っています.
*/
%sganno ; *--アノテート使う準備;
data V_ANNO ;
%SGTEXT(label="↓3.6", x1=3.6, y1=215, drawspace="DATAVALUE") ;
%SGTEXT(label="↓3.8", x1=3.8, y1=27 , drawspace="DATAVALUE", anchor="left") ;
run ;
title "京都のお店1200件 口コミ数順" ;
proc sgplot data=V_OUT sganno=V_ANNO ;
histogram V_VAL / scale=count nbins=40;
xaxis grid
values=(3.0 to 5.0 by 0.2)
offsetmin=0.05
offsetmax=0.05
;
yaxis offsetmax=0.05 ;
run ;
2019年10月25日金曜日
PharmaSUG SDE Tokyo 2019に参加した話
PharmaSUG SDE tokyoに参加した.何やら台風が来ているが無事雨もなく開催となった.傘持つだけで荷物が増えるので持たないとなると荷物が減って楽である.この時は後の雨の悲劇のことなんて知らずにのんきなもんである.六本木なんてオサレタウンに来ることなどないので来るだけで面白い.テレビドラマの広告がこんなにあるなんてなかなか見られない.というか世間にはこんなにドラマがやっていたのか.
前日は簡単な準備と確認.こんなものはおまけなのでさっさと済ませて飲み会へ.私の英語力がなさ過ぎてなんとyesとthank youくらいしか言えることがなくコミュニケーションに支障しかない.すごく気を遣ってくださったのがひしひしと感じるが英語力がついていかない.結局会話の半分くらいしかわからずほうほうの体で飲み会を終えホテルに戻る.めっちゃゆっくりしゃべってくれたことと,適宜話を振ってくださったことに感謝の気持ちしかないほんとありがとうございます.
当日は早めに会場入りをする.普段会社行くより早い時間に起きるとは思いもしなかったが普段が遅すぎるだけか.当日私にできることなんて非常に限られているので隅っこのほうでバタバタと動くしかない.途中でお茶をポロリしたが決して遊んでいるわけではなく大まじめです.ドリフやってんじゃねえのになんで落ちるかな.午後からもパラパラと来場されたので受付が追い付かない部分もあったが大崩れすることもなくまあまあで終われたと思いたい.今年のノベルティはもうちょっとひねれたんじゃないかと反省するが,考えたときにはあれがbestだったので致し方ない.思う存分栓を抜いてください.来年のノベルティがどうなるかは全く未定ですが,ハードルは極めて低いと思いますので是非来年はいいものを誰か考えてくださいね.
会の後は車屋に隣接したオサレ店にて飲み会.会場近くにあんなお店あるとかやはり東京は店の数が違うと実感.ポテト一つとっても美味しかったし何より乾杯がスパークリングワイン.どうせビールと高を括っていたところに運ばれてくるワイングラスは通常の3倍くらい趣があった.いとおかし.sas社の人も参加されていたのでここぞとばかりにviyaの話を聞いてみるが,やはり会社に導入しているbaseSASを置き換えるくらいの規模感で導入しないとお値段がお値段してそうな感じか.機能を絞った相談とかもいけそうな感じがあったが,機械学習系を積まないとviyaの良さがないよなあ.guiでの操作は強いがそこだけならイマイチ感ありますあります.そして機械学習系を積むとお値段がお値段すると...飲み終わりにすげー雨に降られてびしょびしょでホテルに戻ったが今年のPharmaSUGはこれにて終了.皆様ありがとうございました.帰りの新幹線で前日準備の際に頂いたblood orangeのチョコをよばれる.やっぱりチョコのおいしさは共通だね.オレンジがほんのり効いてて甘すぎず,酒が飲めない分茶が進む進む.やっば新幹線で書いてたら気分悪くなってきた
2019年10月1日火曜日
グラフの背景にgrid線を入れる話
グラフをsgplotで書く時に,軸のメモリごとの格子線を背景に入れるオプションの紹介です.英語だとbackgroundgridですかね.これが見つからなくてちょっと時間かかったんですよね...意外とこの手の微妙なオプションがなかなか紹介されていなくて辛い.
yaxis/xaxisステートメントにgridオプションを指定すると目的の格子線が入ります.
例えば以下の画像だとy軸のメモリごとにうっすら格子線が入っています.通常だとこんな線はなく背景は真っ白ですね
/*-以下プログラム-*/
data HOGE ;
do i = 1 to 5 ;
X = i ;
Y = x ;
output ;
end ;
run ;
proc sgplot data = HOGE;
series x = X y = Y ;
xaxis
offsetmax=0.05
offsetmin=0.05
;
yaxis
grid /*これがgridを出すオプション--xaxisにも同じ指定が可能*/
offsetmax=0.05
offsetmin=0.05
;
run ;
yaxis/xaxisステートメントにgridオプションを指定すると目的の格子線が入ります.
例えば以下の画像だとy軸のメモリごとにうっすら格子線が入っています.通常だとこんな線はなく背景は真っ白ですね
/*-以下プログラム-*/
data HOGE ;
do i = 1 to 5 ;
X = i ;
Y = x ;
output ;
end ;
run ;
proc sgplot data = HOGE;
series x = X y = Y ;
xaxis
offsetmax=0.05
offsetmin=0.05
;
yaxis
grid /*これがgridを出すオプション--xaxisにも同じ指定が可能*/
offsetmax=0.05
offsetmin=0.05
;
run ;
2019年9月15日日曜日
sasユーザー会2019に行ってきました
SASユーザー会2019に行ってきた。
去年の台風が思い起こされるも今年は無事晴れ,雨の無い移動はなんと楽なんだろうか.会場が例年と違って赤坂見附と言われても会場の最寄り駅までは何とかなるので大した違いがない.問題は駅から会場までの間である.東京駅から地下鉄に乗って1本,非常にアクセスがよい赤坂見附.会場は大学のキャンパスのようだがこれがまた田舎者には気後れするほどのオサレ会場.惜しむらくは建物内にご飯食べるところがあるにも関わらず「館内イベントのため休業」せっかくのカフェテリアが泣いてるぞ.私の初日のお昼は天下一品になりました.
今年のユーザー会の目玉は何といってもods excelとマクロクォーティングか.マクロクォーティングなんて正直関数を適当に当てはめて意図通りに行ってればokみたいなとこあるので,あれだけきれいにまとまった資料を見ると浅はかな自分が悲しくなる.あんないい感じの資料を公開してくれるのはありがたい話である.
ods excelも気になる.excel2016でddeが怪しいという噂を幾つか聞くので,新しいexcel操作方法は大変気になるところ.実際に使う使わないは別にしてもしもに備えるためにも知るくらいはしといたほうが良いんじゃなかろうか.word2016でデフォルトフォントが変わったおかげでrtf出力でゴタゴタしたと思ったら今度はexcel.officeの更新は影響範囲がとても大きい.
1日目がスムーズに終わったのでホテルに帰って発表練習.日頃から30分も話すことなんてないので口が回らないがなんとか話し終えれるくらいには準備して2日目の発表に備えて早めにお休みする.当日は30分枠のうち25分ほど使って話してしまう.ちょっとギリギリまで話しすぎたせいで質問が中途半端になった.次の機会には少し控えめに構成してみようか.なにせ30分発表なぞこれまでの中でやったことがあまりないので機微がわからない.こればかりは慣れかなあ...
今年のユーザー会も無事終わって何より.来年のめどが何も立っていないが果たして来年はどうなるか,ネタがまにあうのだろうか.
登録:
投稿 (Atom)

