2016年2月26日金曜日

SASHELPのサンプルデータを使おう



ライブラリ「SASHELP」には様々なデータがあり、その中には「サンプルデータ」も格納されています。

  • データは昔のものが多いですが、SAS学習時や、試したい事があった時に重宝します。
  • 各データの意味や出典はリファレンスを参照下さい。
  • SASバージョンや環境によって削除・追加される可能性あり(今回はSAS9.4での内容になります)


【SAS9.4】 SASHELPサンプルデータセット一覧(一部)

データセット名
データセットラベル
メモ
BASEBALL
1986 Baseball Data
メジャーリーガーの成績など。
REGプロシジャの例でよく見かける。
BMIMEN
Body Mass Index and Age for Men
年齢とBMIのデータ
BMT
Bone Marrow Transplant Patients
骨髄移植患者の無病生存期間。
LIFETESTプロシジャの例でよく見かける。
BWEIGHT

Infant Birth Weight
出生時体重と母親に関するデータ
CARS

2004 Car Data

CLASS
Student Data
架空の生徒の性別、年齢、身長、体重データ。
サンプルとしての使用例が多く単純で使い易い。また環境によってデータの中身が日本語訳されている。
COMET

Comet Assay Data
 
ENSO
El Nino Southern Oscillation

FAILURE

MOS Capacitor Failure
 
FISH
Measurements of 159 Fish Caught in Lake Laengelmavesi, Finland

GAS
Nitrogen Oxide Emissions from a Single Cylinder Engine
 
HEART
Framingham Heart Study
 
IRIS
Fisher's Iris Data (1936)
フィッシャーのIRISデータとして有名ですね
JUNKMAIL
Classifying Email as Junk or Not
 
MARGARIN
Margarine Purchase Data

ORSALES
Orion Star Sports & Outdoors Sales 1999 - 2002
 
PRDSAL2

Furniture sales data
 
PRDSAL3

Furniture sales data
 
PRDSALE

Furniture sales data
 
PRICEDATA
Simulated monthly sales data with hierarchy of region, line, product
 
RETAIL
Retail Sales (Quarterly: 1980Q1-1994Q2)

SHOES
Fictitious Shoe Company Data
 
SNACKS

Daily snack food sales
 
STOCKS
Performance of Three Stocks from 1996 to 2005
 
・・・etc


使用例

proc means data=sashelp.class;
 var weight;
 class sex;
run;



2016年2月24日水曜日

「CALL SET」「FETCHOBS」等で、全変数まとめてマクロ変数に格納する。



全変数まとめて同名のマクロ変数に格納する、あまり知られていない方法。
(最後に注意点の記事リンクも貼っているのでそちらも要確認)





%macro TEST;

   * データセットOPEN ;
   %let _DSID = %sysfunc(open( SASHELP.CLASS ));

   * 変数と同名のマクロ変数をリンクさせる ;
   %syscall set( _DSID );

   * OBSの数だけループ ;
   %do _i = 1 %to %sysfunc(attrn( &_DSID, nlobsf ));

        * 1OBS内の全変数値を同名のマクロ変数に格納 ;
        %let _RC = %sysfunc(fetchobs( &_DSID, &_i ));

        * 格納値をログに出力してみる ;
        %put &NAME &SEX &AGE &HEIGHT &WEIGHT;

   %end;

   * データセットCLOSE ;
   %let _RC = %sysfunc(close( &_DSID ));

%mend;


%TEST;


ログ

ログにマクロ変数値が出力されてますね。


注意点

・数値をマクロ変数にいれると、丸められて元の値と異なる場合があるので注意。
マクロ変数に数値をいれて戻すと誤差がでちゃう場合がある問題について考える話(データステップ100万回)

・変数値を格納したマクロ変数の名前が、一時的に作ったマクロ変数の名前(今回の例では「_DSID」「_i」「_RC」)と被らないように気をつけてくださいね。



関連記事

変数値をマクロ変数に格納する方法「CALL SYMPUTX編」


2016年2月18日木曜日

グループ毎に空白行を追加したい



やりたい事

* サンプルデータ ;
data DT1;
length NO SEX $10. AGE HEIGHT 8.;
input NO$ SEX$ AGE HEIGHT @@;
cards;
001 F 25 159.2  002 F 43 161.8  003 F 21 158.1  004 M 19 178.0  005 M 28 160.2
;



変数SEXの値ごとに1行だけ空白行を追加したいとします。




方法① データステップ

proc sort data=DT1;
   by SEX ;
run ;

data OUT1;
   set DT1 ;
   by SEX ;
   output ;
   if last.SEX then do ;
       call missing( NO, AGE, HEIGHT );
       output ;
   end ;
run ;


ざっくり解説すると、
  • output;」でいったん現在のオブザベーションをデータセットに出力
  • if last.SEX then do;」で、SEXの値「F」「M」ごとに最後のオブザベーション(3obsと5obs)を読み込んだ時に、
  • call missing( NO, AGE, HEIGHT )」で変数NO, AGE, HEIGHTを欠損値にして、
  • output;」でデータセットに再出力しています。


📝注意点

ここで使用している「LAST.BY変数」は「サブセット化IF」と一緒に使用すると正しく動かない事があります(解説記事:「サブセット化IFでありがちな落とし穴」)





方法② REPORTプロシジャ

proc report data=DT1 out=OUT2 nowd ;
   define _numeric_  / display ;
   define SEX  / order order=internal missing ;
   break after SEX  / ;
run ;


REPORTプロシジャってデータセットにも出力できるんです!

  • define SEX / order order=internal missing;」と「break after SEX /;」で、SEX毎に要約行を追加
    • この書き方、HTML等への出力時には要約行が入らないんですが、データセット出力時には要約行が入ります
  • このままだと要約行に数値変数AGE, HEIGHTの要約値(合計)が入ってしまうので、「define _numeric_ / display;」で全数値変数を集計せずただdisplayするだけ(表示するだけ)にしています(データセット中に数値変数が存在しないなら「define _numeric_ / display;」は不要)
  • out=OUT2」でデータセットOUT2に出力


他に何かいいアイディアがあれば教えてください!


指定した変数をすべて欠損値にする【CALL MISSING】


CALL MISSING を使うと、指定した変数をまとめて欠損値にできます。


構文


  CALL MISSING( 変数1, 変数2, ・・・)


  • 数値変数と文字変数まとめて指定可能
  • 通常のデータセット以外で使用すると、WARNINGが出て機能しない事があるらしい?ので、ログとかも確認するようにして下さい。詳細不明なので、何かご存じの方いたら、教えて下さい




*** サンプルデータ ;
data DT1;
  length A1 A2 8. A3 $10.;
  A1=1;
  A2=2;
  A3="aaa";
run;
  A1  
  A2  
  A3   
    1    2  aaa

*** まとめて欠損値にする ;
data DT2;
  set DT1;
  call missing( A1, A2, A3 );
run;
  A1  
  A2  
  A3   
    .    .  


さらに of を使えばいっぺんに変数指定が可能。

call missing( of A1-A3 );  
→ A1~A3まで連番の変数すべて
(「of」をつけ忘れると「A1-A3」で引き算の意味になっちゃうので注意)

call missing( of _all_ );
→ 全変数

call missing( of _numeric_ );
→全数値変数

call missing( of _character_ );
→全文字変数


2016年2月16日火曜日

【SAS入門】 DATAステップとPROCステップ





SASの処理は 「DATAステップ」と「PROCステップ」というものに分かれます。




DATAステップ


ざっくりした解説ですが、自分が処理したいことをDATAステップにゴリゴリ書いていきます。


DATAステップの基本構文
 data ・・・;
     ~処理したいことを書く~
 run ;



data TEST;
  A=1;
  B=2;
  C=3;
run;

上の例では、TESTというデータを作り、以下の処理をしています。

Aという項目に「1」を代入
Bという項目に「2」を代入
Cという項目に「3」を代入




PROCステップ


決まった処理を一括で行ってくれるのがPROCステップで、たとえば

・データを集計したい → MEANSプロシジャ
・データを転置したい → TRANSPOSEプロシジャ
・データの中身を出力したい → PRINTプロシジャ

といった具合にDATAステップでは面倒な処理を自動で処理してくれるプロシジャというものが用意されています。


PROCステップの基本構文
 proc  プロシジャ名 ;
   ~詳細設定等~
 run ;



proc print data=TEST;
run;

データ「TEST」の中身を出力するために、PRINTプロシジャを使っている例です。




2016年2月15日月曜日

REPORT(またはPRINT)プロシジャで罫線の引き方を設定する。


※ ODS RTF, PDF等、一部の出力先でのみ設定できます。詳細はリファレンスを参照下さい。
(設定可能なはずの一部のODS出力先で正しい動きをしない場合があったので、各自、各環境でテストしたほうが良さそうです)



構文


 PROC REPORT  STYLE( REPORT )=[ RULES=設定1  FRAME=設定2 ];
 RUN;



RULES = 内側の罫線
 指定 設定内容
 NONE  罫線なし 
 COLS   縦罫線のみ 
 ROWS  横罫線のみ 
 ALL   縦横すべて 
 GROUPS  表ヘッダーとデータの切り替わり部分に罫線を引く。
 データと表フッターの切り替わり部分にも罫線を引く 。
 表ヘッダーや表フッターがないと罫線は引かれない。

 FRAME = 外側の罫線
 指定 設定内容 
 VOID 罫線なし 
 ABOVE   上のみ 
 BELOW  下のみ 
 LHS   左のみ 
 RHS  右のみ 
 HSIDES 上下のみ   
 VSIDES  左右のみ 
 BOX  上下左右 





ods rtf file="出力パスを指定\TEST.rtf";

proc report data=SASHELP.CLASS(obs=5)
         style(header)=[background=white]
         style(report)=[rules=groups frame=hsides] ;
   column SEX NAME AGE;
   define SEX / display;
   define NAME / display;
   define AGE / display;
run;

ods rtf close;





関連

REPORTプロシジャ入門8:書式の設定【STYLE=】
【PROC REPORT】RTF出力時の細かい罫線の設定

2016年2月10日水曜日

REPORTプロシジャ入門9:特定セルの書式設定【CALL DEFINE】




前回 「書式の設定【STYLE=】」 の応用。
「CALL DEFINE」 で、特定の行または列だけ書式を設定する事ができます。



基本構文

COMPUTE  対象変数;
           CALL DEFINE( "対象変数", "STYLE", "STYLE=[スタイル設定]");
ENDCOMP;


諸注意
  • STYLE=は、ODS LISTGNG出力先には対応していないので、ご注意下さい。
  • CALL DEFINEを複数定義すると、うまく適用できない場合があります(記事の最後に関連記事のリンク貼ってます)



では、例をみていきます。



列の書式設定 ①

proc report data=SASHELP.CLASS nowd;
    column NAME AGE ;
    define   NAME  / display;
    define   AGE    / display;
    compute AGE;
       call define( "AGE", "style", "style=[color=blue]" );
    endcomp;
run;


以下のように「_COL_」と書いてもOK

    compute AGE;
       call define( _COL_ , "style", "style=[color=blue]" );
    endcomp;

(こう書くと、COMPUTEステートメントに書かれた変数AGEが対象になる。)




列の書式設定 ②

proc report data=SASHELP.CLASS nowd;
    column NAME AGE HEIGHT;
    define   NAME    / display;
    define   AGE       / display;
    define   HEIGHT  / display;
    compute AGE;
       if AGE > 13 then call define("NAME","style","style=[color=blue]");
    endcomp;
run;


ここで注意!
NAMEに対する書式設定ですが、「compute NAME;」 ではなく 「compute AGE;」と指定しています。
なぜかというと、、以下ルールに従っているからです。


①  COMPUTEステートメント内で使われている変数はAGEとNAMEです。
②  このAGEとNAMEのうち、COLUMNステートメントで一番後ろに指定されている変数はAGEです。
③  よって 「compute AGE;」 とする。

ちなみに「compute HEIGHT;」としてもOK。
(COLUMNステートメントでHEIGHTの方がNAMEやAGEより後ろに指定されているから)




行の書式設定

proc report data=SASHELP.CLASS nowd;
    column NAME AGE HEIGHT;
    define   NAME    / display;
    define   AGE       / display;
    define   HEIGHT  / display;
    compute AGE;
       if AGE > 13 then call define( _ROW_, "style", "style=[color=blue]" );
    endcomp;
run;

_ROW_」で該当の行全体に対して書式設定を行います。



📝ちなみに、、

CALL DEFINEを複数定義すると、うまく適用できない場合があります。
【PROC REPORT】1つの項目に複数のCALL DEFINEを定義したい


インラインフォーマットを組み合わせると、更に自由度の高い書式設定が行えます。
ODS出力時に文字の書式設定をする【インラインフォーマット】


最後にCOMPUTEステートメントを使う上で超重要&ありがちな落とし穴もあるので、ちょっと前提知識必要になるけど、是非ご覧ください。
「PROC REPORT」の「COMPUTE」がうまく動かないんだけど
「PROC REPORT」の「COMPUTE」がうまく動かないんだけど②



REPORTプロシジャ入門記事一覧

1.基本構文【COLUMN, DEFINE】
2.ヘッダーの設定
3.並べ替え・グループ化【ORDER, GROUP】
4.集計【ANALYSIS】
5.転置集計【ACROSS】

2016年2月1日月曜日

REPORTプロシジャ入門8:書式の設定【STYLE=】



ODS LISTING以外の、ODS RTF, HTML, PDF等の出力先では、STYLEオプションを使ってセルの書式設定ができます。


構文

STYLE(  設定場所  ) = [ 書式1  書式2 ・・・]


設定場所
 指定 設定場所 
 HEADER   ヘッダー(項目名) 
 COLUMN   中身のデータ 
 SUMMARY   要約行
 ・・・など    


書式
・「設定場所」によっては書式設定が効かない場合あり
・RTF, HTML等の出力先毎に設定可能な書式が違うのでリファレンスも要参照
 指定 設定内容  例 
 FONTFAMILY   フォント  fontfamily='MS P明朝' 
 FONTSIZE  文字サイズ  fontsize=10pt
 FONTWEIGHT  文字の太さ  fontweight=bold 
 FONTSTYLE 斜体等のスタイル  fontstyle=italic
 COLOR 文字色 color = blue
 BACKGROUNDCOLOR   セル色 backgroundcolor = yellow 
 WIDTH  セルの横幅 width = 3cm
 HEIGHT セルの高さ height = 3cm
 TEXTALIGN  文字の横位置 textalign = left
 VERTICALALIGN 文字の縦位置 verticalalign = center
 ・・・ など




では、例を見ていきます。
以降の例は、HTMLへの出力が有効になっている前提です。


レポート全体の書式設定

proc report data=SASHELP.CLASS nowd style(column)=[color=blue];
   column  NAME AGE;
   define  NAME / display;
   define  AGE    / display;
run;





項目ごとの書式設定

proc report data=SASHELP.CLASS nowd;
   column  NAME AGE;
   define  NAME  / display style(column) = [color=blue] ;
   define  AGE     / display style(header) = [background=yellow] ;
run;





ちなみに、、


以下のように HEADER や COLUMN などは一度に複数定義できます。
*OK;
define  NAME / display style(header) = [background=yellow]
                                   style(column) = [color=blue]  ;



また、PRINTプロシジャ等、一部のプロシジャでもSTYLEオプションが使えちゃいます。
proc print data=SASHELP.CLASS ;
   var NAME /  style(column)=[color=blue];
   var AGE;
run;

📝