2.3K Views
December 17, 24
スライド概要
SAS言語を中心として,解析業務担当者・プログラマなのコミュニティを活性化したいです
ゼロからでも始められる SAS プログラミングのエッセンス イーピーエス株式会社 森岡裕
学習のため無料でSASを利用する場合 SAS® OnDemand for Academics https://www.sas.com/ja_jp/software/on-demand-for-academics.html メールアドレスからアカウント(SAS profile)を 登録すれば利用可能. ブラウザ上でSAS Studioというインターフェースを介し てSASプログラムを実行可能 商用利用は不可. 手元のデータを参照する場合は一旦クラウド環境に アップロードが必要(個人情報を含むものは禁止) 予測入力補助と,ヘルプ参照があるため学習向き
アカデミア向けSASライセンス Education Analytical Suite https://www.sas.com/ja_jp/software/education-analytical-suite.html
https://www.sas.com/ja_jp/contact/form/register.html 筒井杏奈「アカデミアにおけるSAS利用時の不明点と解決策」より転載 https://www.docswell.com/s/6484025/KV161P2024-10-21-155339
プログラム言語としての人気 言語の人気としては最近は ,TIOBEでみるとRが15~20位あたりに位置して,その5位ぐらい下 20~25位ぐらいをウロウロしてるイメージ 2024にIEEEのJobs(雇用機会)の重み付けでランキングを 5 位だったりして話題になったり 2024/11/20アクセス https://www.tiobe.com/tiobe-index/ https://spectrum.ieee.org/top-programming-languages-2024
臨床のデータサイエンスでSASを使う意味 以下はすべて,OSS(主としてRとPython)と比較して,という意味であり,発表者の主観が含まれます ・言語として,時間的前後の互換性が高い. バージョンによる破壊的な文法の刷新がほぼなく,製品版であるため,機能の管理やリファレンスが しっかりしている.良くも悪くもであるが,言語としてはレトロで枯れているため,20年前のプログラムを最新の 環境で動かしても,そのまま実行できることが多い 臨床試験のデータハンドリング・解析プログラムは過去の類似試験の枠組みを利用し,組織内で長期に運用される ことが多いため,管理上優れている ・ミニマムなサイズのデータであれば,プログラマ練度によらず一定の処理速度を保てる リアルワールドデータやデータベース研究を除き,臨床試験におけるデータハンドリングや統計解析を考える場合, どんなに大きい試験であってもビックデータとはならない.その場合,SASはどれだけ初心者が冗長なコードで解 析したとしても,上級者が書くのとそれほど処理時間は変わらない 良くも悪くも文法がレトロで,機能が,限定してデータハンドリングと解析に特化しているため ・統計学の視点から,リファレンスに一定以上の質と保証がある 統計解析分野の有償製品ソフトの最大の強み.SASに実装されている統計手法について,SAS社の統計学者が常に 監修しており,リファレンスも記載粒度や説明に一貫性がある.リファレンス内ではかなりの細かさですべて論文 参照と詳細説明に繋がっており,全体の統一感や記載の正確さなど,総合的な品質管理が高度.
ネガティブ要素 ・費用が高い. 商用の解析ソフトウェアの宿命.ただ,若干,イメージによるものも大きいかも.前述のアカデミア向けライセン スもそうであるが,ちゃんとSAS社問い合わせで見積もりしてもいただければ,世間一般でいうとんでもない値段 とは言えないことが多い気がしています ・プログラムが難しい 難しくはない.むしろ40年以上前からほとんど変わっておらず,過度にシンプルではある. 難しいというよりかは,現代的な言語との距離が遠くなってきたため,異質に映り忌避されるきらいがある 特に後述しますが,R言語のマトリクス処理構造と,SASのオブザベーション処理構造が,根本から異なっているた め,Rを習得したのちにSASを学ぶと,混乱から不自由を感じ,「なんじゃこれ.なんでこんなこともできないん だ」ってなる. ・情報が少ない.最新の解析手法や,込み入った手法が実装されていない 商用ソフトウェアがOSSにどうしてもひけをとる点.こればかりは,有償である以上,無償ソフトのユーザー数を 上回ることは難しく,また企業が管理しているため,パッケージとして個人が仕組みを作成して製品に取り入れる ということは難しい
本資料は とりあえず,他人のSASコードをみて,なんとなくなにやってるのかわかる できるだけ,コードとその出力結果をのせて,なんとなくSASプログラムの 勘所,エッセンスを感じてもらうことを目的にします
「エクスプローラ」「アウトプット」「ログ」「エディタ」がウインドウとして表示
最近のプロシジャ出力やグラフ出力はアウトプットウインドウではなく 「結果ビュワー」にHTML出力されることがデフォルトなので,画面構成は適宜調整すればよい カスタマイズしても 一度SASを閉じてしまうとリセット されるので 「ツール」→「オプション」→「プ リファレンス」から「終了時の設定 を保存する」にチェック
「ライブラリ」はデータ(SASデータセット)のロケーション に名前を付けたもの SASの場合,他の言語と,色々なキーワードの使われ方が異なるので注意 libname xxx "D:\Users\aaaaa\Desktop\test"; libnameステートメントでディレクトリに SAS内で参照できるための 名前をつけることができる
SASHELPという,強制的に必ず存在するライブラリの中にはサンプルデータセットが既にたくさん用意さ れている ダブルクリックすれば,データセットビュー という形でみることができる 他の言語でも有名な,フィッシャーのあやめデータ「iris」 SASは行を 「オブザベーション」 列を 「変数」 と呼びます. そのためレコード番号や 行番号の意味で オブザベーション番号と いいます
data work.test; set sashelp.class; run; これをF3またはF8キー,もしくは をクリックで実行すると ログ運動に SASHELP.CLASSから19オブザベーション読みこみ,WORK.TESTに19オブザベーションあ ることが表示されます dataステートメント から 始まり,runステートメントで終わる,一つの実行単位を データステップと呼びます.Setステートメントは「ライブラリ名.データセット名」で指定したデータセッ トを移動させることができます Workライブラリはテンポラリーのライブラリで,そこに存在するデータセットはSASを閉じれば自動的にクリアさ れます.残したいデータセットはlibnameステートメントで名前をつけたライブラリにsetすることで,SASデータ セット形式(.sas7bdat)として残ります.Workライブラリにたいして永久ライブラリと呼称します
データの抽出 data test; set sashelp.class; where AGE = 12; run; data test; set sashelp.class; if AGE = 12; run; data test; set sashelp.class; if AGE = 12 then output; run; Work.testとしていないのに Workライブラリにデータセットが作成され るのはWorkのみ,省略すると自動で記載し ているとみなされるようになっている Where ステートメント+条件式 抽出できます.抽出元のデータセットにあらかじめ存在している変数を 使って抽出を行う場合は速度的にwhereステートメント一択になります.データステップの中で作成した 変数を使って絞りたい場合は if ステートメントも利用可能です. If ステートメントはthenとあわせて条件式でも利用されるので,thenなしで抽出のために利用される場合 はサブセットIFと呼称します
データの抽出 data test1; set sashelp.class; where AGE=12; where same SEX="男子"; where same 58 <= WEIGHT; run; data test1; set sashelp.class; where AGE=12 and SEX="男子" and 58 <= WEIGHT; run; 条件はwhere sameやandで追加できます data test1; set sashelp.class; where AGE=12; /* where same SEX="男子";*/ where same 58 <= WEIGHT; run; /**/でくくった部分はコメントとなり 実行に影響を及ぼさなくなります
新しい変数の追加(割り当てステートメント) data test1; set sashelp.class; BMI = WEIGHT * 703 / HEIGHT**2 ; if 18<=BMI<=20; run; BMIを計算して,そのBMIが18以上,20以下のオブザベーションのみを抽出しています もとのデータセットにはBMIは存在せず,データステップの中で作成したので この場合はwhereステートメントは使えずにサブセットIFになります Rでいう <- も 比較演算子の == もSASでも両方「=」を使いますので,文脈によって それが割り当てステートメント(新しい変数を作るための=)か比較演算子としての等号なのかが変わります
条件分岐 data test1; set sashelp.class; if . < AGE <= 12 then AGEGRP="12歳以下"; else AGEGRP="12歳超"; run; SASでは数値の欠損をピリオド「.」で表現し,大小比較においては常に無限に小さいものとして扱われます data test1; set sashelp.class; if 12 <= AGE <= 13 then AGEGRP="12-13歳"; else if 14 <= AGE <= 15 then AGEGRP="14-15歳"; else if 16 <= AGE then AGEGRP="16歳以上"; else put "WARNING:"AGE=; run;
条件分岐 data test1; set sashelp.class; data test1; select; set sashelp.class; when(SEX="男子") SEXN=1; select(SEX); when(SEX="女子") SEXN=2; when("男子") SEXN=1; when("") ; when("女子") SEXN=2; otherwise put "WARNING:" SEX=; when("") ; end; otherwise put "WARNING:" SEX=; run; data test1; end; set sashelp.class; run; select(SEX); when("女子") do; data test1; SEX_E="Female"; set sashelp.class; SEXN=1; if SEX="女子" then do; do-endを使うと end; SEX_E="Female"; 複数のステートメントを when("男子") do; SEXN=1; ひとまとめにできる SEX_E="Male"; end; SEXN=2; if SEX="男子" then do; end; SEX_E="Male"; when("") ; SEXN=2; otherwise put "WARNING:" SEX=; end; end; run; run;
条件分岐 data test1; set sashelp.class; data test1; select; set sashelp.class; when(SEX="男子") SEXN=1; select(SEX); when(SEX="女子") SEXN=2; when("男子") SEXN=1; when("") ; when("女子") SEXN=2; otherwise put "WARNING:" SEX=; when("") ; end; otherwise put "WARNING:" SEX=; run; data test1; end; set sashelp.class; run; select(SEX); when("女子") do; data test1; SEX_E="Female"; set sashelp.class; SEXN=1; if SEX="女子" then do; do-endを使うと end; SEX_E="Female"; 複数のステートメントを when("男子") do; SEXN=1; ひとまとめにできる SEX_E="Male"; end; SEXN=2; if SEX="男子" then do; end; SEX_E="Male"; when("") ; SEXN=2; otherwise put "WARNING:" SEX=; end; end; run; run;
ちょっと 休憩・寄り道
SASって PDVといわれる1オブザベーションごとの作業場 data a; set a; a = a + 2; run; +2 SASは暗黙的に,データステップに書かれた処理を 繰り返している 1オブザベーションを読み込んで,操作し,1オブザベーションをアウトプットに移すという手順を オブザベーション分繰り返している 22
SASとRの違いって 私見ですが SASとRの違いの根本はここだと思ってます SASは,観測に対して,処理を暗黙にループすることで捌いており Rはベクトルの処理に帰着させることで捌いている 23
ソート proc sort data=sashelp.class out=test2; by AGE descending WEIGHT; run; 年齢で昇順,次に体重で降順に並び替えて いる data ~ run;構造のデータス テップと異なり proc ~ run(quit)構造のもの を プロシジャステップという Pocのあとにプロシジャ名がく る.プロシジャには例のsortプ ロシジャのようにデータセッ トの構造をかえるものや,グ ラフを描くもの,統計処理を するものなど色々ある
ソート proc sort data=sashelp.class out=test2; by AGE descending WEIGHT; run; data test3; set test2; by AGE descending WEIGHT; if first.AGE then note=cats(AGE,"歳で一番軽い"); if last.AGE then note=cats(AGE,"歳で一番重い"); drop HEIGHT SEX; run; ソートしたデータセットはsetの際にbyが利用でき,それによって,ソートされたグループの中でもっとも先頭の もの,最後のものという条件で first.変数 last.変数のフラグを処理にいれることができる
結合(横結合) data wk1; length Name $12.; Name="ジョン";val=1;output; Name="ロバート";val=2;output; Name="ケン";val=3;output; run; data ds1; set sahelp.class; keep Name Age; run;
結合(横結合) proc sort data=ds1; by Name; run; proc sort data=wk1 ; by Name; run; data m1; merge ds1 wk1; by Name; run; Mergeステートメントで複数のデータセットを横結合する場合,あらかじめ全てのデータセットがキーとなる すべての変数でソートされている必要がある
結合(横結合) data m2; merge ds1(in=in1) wk1(in=in2); by Name; if in1; run; data m3; merge ds1(in=in1) wk1(in=in2); by Name; if in2; run; data m4; merge ds1(in=in1) wk1(in=in2); by Name; if in1 and in2; run; このように,いわゆる左(右)外部結合や 内部結合は( )ないにin=というデータセットオプションを設定 し, それをサブセットIFと併用することで 左のデータセットにあるものを必ず残す(左側外部結合) 両方のデータセットにあるものを残す(内部結合) といったデータベースでの結合に類似の挙動を実現する ※複数のデータセットからソート順で順番に読み込んで上書き しているのが実態なので厳密にはSQLのJointとは異質な処理
結合(横結合) プロシジャステップ内で任意のSQL文を実行できるSQLプロシジャや /*SQL*/ ハッシュテーブル(連想配列)でkey-data構造をメソッドで操作できる proc sql; ハッシュオブジェクト等の機能もあるので create table sql1 as 必ずしもすべてにおいてSASの文法に縛られる必要はない. select a.Name PythonやLuaなども部分的に取り込む機能もあるので,他言語の知識は ,Age ある程度活きる ,val from ds1 as a left outer join wk1 as b /*結果はどちらも同じ左側外部結合*/ on a.Name = b.Name ; quit; /*ハッシュオブジェクト*/ data hash1; set ds1; if 0 then set wk1; if _N_ = 1 then do; declare hash h1(dataset:"wk1"); h1.definekey("Name"); h1.definedata("val"); h1.definedone(); end; if h1.find() ne 0 then call missing(of val);; run;
転置(横持ち→縦持ち) proc sort data=sashelp.class out=out1; by Name; run; proc transpose data=out1 out=out2; var AGE WEIGHT HEIGHT; by Name; run;
転置(縦持ち→横持ち) proc transpose data=out2 out=out3(drop=_NAME_); var col1; by Name; id _NAME_; run;
統計解析 単変量に対して様々な統計量を算出するunivariateプロシジャ proc univariate data=sashelp.class; var weight; run;
統計解析 ttestプロシジャで性別間で体重の平均の差の検定(対応のないt検定) Pooledがstudentのt検定でSatterhwaiteがウェルチのt検定 proc ttest data=sashelp.class; class sex; var weight; run;
統計解析 freqプロシジャでクロス集計とカイ二乗&フィッシャーの正確検定 proc freq data=sashelp.class; table sex * age / chisq fisher; run; クロス表のスパースが酷い場合,カイ二乗検定が妥当で はないといった教育的なメッセージがでる
統計解析 Corrプロシジャで相関マトリクス(ピアソン・スピアマン両方) proc corr data=sashelp.class pearson spearman ; var age weight height ; run;
統計解析 Regプロシジャで重回帰分析 data class; set sashelp.class; if SEX="男子" then SEXN=1; else SEXN=2; run; proc reg data=class ; model WEIGHT = AGE HEIGHT SEXN; run; quit;
統計解析 logisticプロシジャでロジスティック回帰 (応答変数=性別(女子)) proc logistic data=class ; model SEX = AGE HEIGHT WEIGHT; run;
統計解析 glmプロシジャで分散分析 glmプロシジャは一般化線形モデル の枠組みで 色々できる
「SAS Help Center」と共に知りたいキーワードを入れてウェブ検索すると 公式リファレンスの該当するプロシ ジャにあたりやすい. 仕様単語が限定され,平易な英語になるようにされた記載のため読みやすく,機械翻訳しやすい 必ずexampleに再現可能な解析とその解釈の仕方が書かれているので親切
レポーティング proc odstable data=sashelp.class; column Name (Sex Age) Weight height; define header header1; start=Name; end=Name;just=left; text "名前"; end; define header header2; start=SEX; end=Age;just=left;split="#"; text "性別#年齢"; end; define header header3; start=Weight; end=Height;just=left;split="#"; text "身長体重"; end; define header header3_1; start=Weight; end=Weight;just=left;split="#"; text "身長"; end; define header header3_2; start=Height; end=Height;just=left;split="#"; text "体重"; end; define Name; print_headers=off; just=left; style={cellwidth=200}; end; define SEX; print_headers=off; just=left; style={cellwidth=100}; end; define AGE; print_headers=off; just=left; style={cellwidth=100}; end; define Weight; print_headers=off; just=left; style={cellwidth=100}; end; define Height; print_headers=off; just=left; style={cellwidth=100}; end; run;
レポーティング Excelファイルへレポート ods excel; proc odstable data=sashelp.class; ーー中略ーー run; ods excel close; odsは Output Delivery Systemの略で プロシジャステップを実行した際に結果ビューに表示さ れるアウトプットを 別形式のファイルに流し込むことができる
レポーティング RTFファイルへレポート ods rtf; proc odstable data=sashelp.class; ods rtf ーー中略ーー run; ods rtf close; ods pdf Ods powerpoint
ODSは解析アウトプットの データセット化にも使う ods output ParameterEstimates = out; proc reg data=class ; model WEIGHT = AGE HEIGHT SEXN; run; quit;
グラフ proc sgplot data=sashelp.class; scatter y=weight x=height; run; proc sgplot data=sashelp.class; vbox height / category=sex; run; proc sgplot data=sashelp.class; vbox height / category=sex; scatter y=height x=sex/ jitter markerattrs=(symbol=circlefilled size=9); run; 基本的にはSGPLOTプロシ ジャの中にplotステートメン トを入れてグラフを重ねて構 成していくイメージなので PythonのmatplotlibやRの ggplot2と比べて,SASのビ ジュアライゼーションが著し く使いにくい,見栄え悪いと いうことはないように感じる (個人の感想です)
どうやって勉強するのか SAS Help Centerから公式のリファレンスを読んだり,少し日本語訳が怪しいところもあるが,特にデータ ステップ周りなどは日本語化されている部分が多いので,読んだり.あとは割とサクサク動くのでとりあ えず書いては実行して,どうなるか見るのを繰り返せるのが個人的には好き 【日本語書籍のおススメ】 統計解析ソフト「SAS」 改訂版 高浪 洋平 (著), 舟尾 暢男 (著) 【日本語サイトのおススメ】 https://sas-boubi.blogspot.com/ https://sas-boubi.blogspot.com/
どうやって勉強するのか 世界中のSAS関連のフォーラムで発表されたPaperやスライドが4万本近く登録されているので検索すれば だいたい,世界のどなたかが既に 答えを見つけている https://www.lexjansen.com/
どうやって勉強するのか 毎年300人近くのSASユーザーが集まって2日間情報交換しあうSASユーザー総会というものがあります
どうやって勉強するのか 大阪SAS勉教会というものも不定期でやってます. どなたでもご参加ください(リモートでも参加できるようにしてます) https://sites.google.com/view/osakasasbenkyokai/%E3%83%9B%E3%83%BC%E3%83%A0
データサイエンスを楽しむための手段に過ぎないので,なんでもいい と思ってます 選択肢は多いほうがよく,製品版の有償ソフトウェアもそれはそれで 結構いいところがあって,必要存在だなって思ってます この,かごしまデータ科学シンポジウムもそうですが,みんながワイ ワイと色んな話題を議論して情報交換できる場は非常に重要だと感じ てます. 私はSAS周りで今後も発信していこうかと思ってますが,少しでも刺 激やお役に立てれば幸いです ご清聴ありがとうございました!!