ラベル プロシジャ: MEANS の投稿を表示しています。 すべての投稿を表示
ラベル プロシジャ: MEANS の投稿を表示しています。 すべての投稿を表示

2018年12月6日木曜日

【PROC MEANS】OUTPUTステートメントでの出力変数の指定方法



PROC MEANS(または PROC SUMMARY)の「OUTPUTステートメント」で統計量をデータセットに出力することが出来ます。


今回は統計量を出力する際の変数の指定方法を紹介したいと思います。




例① 分析変数が1つの場合


proc means data=SASHELP.CLASS;
   var HEIGHT;
   output out=OUT1  min=MIN_HEI  max=MAX_HEI;
run;

または

proc means data=SASHELP.CLASS;
   var HEIGHT;
   output out=OUT2  min( HEIGHT )=MIN_HEI  max( HEIGHT )=MAX_HEI;
run;


・HEIGHTの最小値をMIN_HEI、最大値をMAX_HEIに格納してます。

・基本的に「統計量( 分析変数 ) = 出力変数」という構文ですが、「統計量 = 出力変数」というように分析変数を省略した場合は、VARステートメントに指定した分析変数が使用されます。






例② 分析変数が2つ以上の場合


proc means data=SASHELP.CLASS;
   var HEIGHT WEIGHT;
   output out=OUT3  min = MIN_HEI  MIN_WEI
                              max = MAX_HEI  MAX_WEI;
run;

または

proc means data=SASHELP.CLASS;
   var HEIGHT WEIGHT;
   output out=OUT4  min( HEIGHT WEIGHT ) = MIN_HEI MIN_WEI
                              max( HEIGHT WEIGHT ) = MAX_HEI MAX_WEI;
run;

またはまたは

proc means data=SASHELP.CLASS;
   var HEIGHT WEIGHT;
   output out=OUT5  min( HEIGHT )=MIN_HEI  min( WEIGHT )=MIN_WEI
                              max( HEIGHT )=MAX_HEI  max( WEIGHT )=MAX_WEI;
run;


・HEIGHTとWEIGHTの最小値をそれぞれMIN_HEI、MIN_WEIに格納
・HEIGHTとWEIGHTの最大値をそれぞれMAX_HEI、MAX_WEIに格納




AUTONAMEオプションの利用

proc means data=SASHELP.CLASS;
   var HEIGHT WEIGHT;
   output out=OUT6  min=  max= / autoname;
run;


AUTONAMEオプションをつけると、SASが自動で出力変数名を決めてくれます。
「分析変数名_統計量」という感じの変数名がつけられます。
作成された変数名の長さがSASの制限を超える場合は変数名が切り捨てられるので注意


以下のような書き方も。

proc means data=SASHELP.CLASS;
   var HEIGHT WEIGHT;
   output out=OUT7  min( HEIGHT )= / autoname;
run;




ちなみに指定出来る統計量は、、
  統計量   内容
  N   N
  NMISS  欠損値の数 
  SUM  合計
  MEAN  平均値
  MIN  最小値
  MEDIAN   中央値
  MAX   最大値   
  RANGE  範囲
  MODE  最頻値   
  STDDEV  標準偏差   
  STDERR  標準誤差   
  Q1  下側四分位点 
  Q3  上側四分位点  
  QRANGE  四分位範囲  
  KURT  尖度
  SKEW  歪度
  …etc

など、その他豊富に取り揃えています。詳細はリファレンスを参照ください。




2017年3月21日火曜日

欠損値の分類も集計に含めるMISSINGオプションと落とし穴



多くの集計用プロシジャでは、分類変数が欠損値のオブザベーションを集計から除きます。



サンプルデータ

data DT1;
input A B C;
cards;
1 1 10
. 1 10
2 1 10
. 1 10
;


変数Aには欠損値が含まれてます。



分類に欠損値が含まれている場合の集計結果

proc freq での例

proc freq data=DT1;
   tables A * B;
run;









変数Aの欠損値2オブザベーションが集計から除かれています。
欠損値も含め集計したい場合、missingオプションをつけます。

proc freq data=DT1;
   tables A * B / missing;
run;



同様に proc means や proc summary でもclass変数が欠損値のオブザベーションは集計から除かれます。
missingオプションをつけるとclass変数が欠損値のものも含め集計されます。

proc means data=DT1;
   class A / missing;
   var C;
run;


proc tabulateも同様。

proc tabulate data=DT1;
   class A / missing;
   table A;
run;




落とし穴①

まずは、proc freq の「なんじゃそりゃ」という落とし穴(proc means や proc tabulateでは問題なさそう)
以下の例をご覧ください。

proc format;
   value A_
      . , 1 = "Missing and One"
      2 = "Two"
   ;
run;

proc freq data=DT1;
   tables A * B;
   format A A_.;
run;



変数Aに欠損値と1をまとめた "Missing and One" というフォーマットを設定して集計しています。
missingオプションを設定していないので、欠損値は集計から除かれますが、なんと、、A=1も欠損値の扱いになって集計から除かれています。

フォーマットで欠損値と非欠損値を1つのカテゴリにまとめた場合、
実データに欠損値が存在すると、同じカテゴリの非欠損値のデータも巻き込んで、欠損値の扱いにしてしまうようです。



落とし穴②

既にSASYAMAさんが記事にされているので、そちらをご覧ください。
means summaryプロシジャのclassステートメント指定変数の欠損値には気を付けてって話

classステートメントに変数を複数指定する場合は注意という話です。
class変数のいずれかに欠損値が含まれている場合、missingオプションがないとそのオブザベーションが全ての集計から除かれてしまいます。



落とし穴③

これも上のSASYAMAさんの記事で注意喚起されていますが、
proc means や proc summary の outputステートメントで集計結果をデータセットに出力すると、

proc means data=DT1;
   class A B / missing;
   var C;
   output out=OUT1 n= mean= / autoname;
run;

集計結果:結果ビューア

集計結果:出力データセットOUT1

出力データセットの方は、結果ビューアにない組み合わせも出力されています。
例えば、出力データセットの1行目は変数AとBの分類全体に対する集計結果です(ただしmissingオプションがない場合、変数AかBが欠損値のオブザベーションは除いたうえで集計される)

特にmissingオプションを設定していると、どの組み合わせに対する集計なのか、分かりづらいです(例:1行目と3行目)


変数_TYPE_で上記の違いを区別することが出来るものの、「紛らわしいので要らない!」というケースがほとんどなので、、

proc means data=DT1 nway;
   class A B / missing;
   var C;
   output out=OUT1 n= mean= / autoname;
run;

nwayオプションで結果ビューアと同じ組み合わせの数に減らせます。


2016年3月23日水曜日

SASで基本統計量を求める 【MEANSプロシジャ】




基本構文

PROC  MEANS  DATA=対象データセット;
      VAR  分析変数 ;
RUN;



基本統計量を出力

proc means data=SASHELP.CLASS ;
   var AGE;
run;




グループ分けして基本統計量を出力

proc means data=SASHELP.CLASS ;
   var AGE;
   class SEX;
run;


CLASSステートメントで、グループ分けして基本統計量を出力する事が出来ます。
上の例ではSEXの値「F」「M」毎に基本統計量を出しています。


ただし、CLASS変数が欠損値のオブザベーションは集計から除かれます。
欠損値も含めるには「CLASS 分類変数 / MISSING;」と記述します(詳細は以下記事を参照)

http://sas-boubi.blogspot.com/2017/03/missing_21.html




表示する統計量を指定する

proc means data=SASHELP.CLASS n min median max q1 q3 range;
   var AGE;
run;




表示したい統計量を指定できます。
  統計量   内容
  N   非欠損値の数
  NMISS  欠損値の数 
  SUM  合計
  MEAN  平均値
  MIN  最小値
  MEDIAN   中央値
  MAX   最大値   
  RANGE  範囲
  MODE  最頻値   
  STDDEV  標準偏差   
  STDERR  標準誤差   
  Q1  下側四分位点 
  Q3  上側四分位点  
  QRANGE  四分位範囲  
  KURT  尖度
  SKEW  歪度
  …etc


2015年7月30日木曜日

集計結果をデータセット化する場合、MEANSよりSUMAMYプロシジャの方が効率的



サンプル作成

data DT1;
input A B @@;
cards;
3 10  2 20  1 30
;



SUMMARYプロシジャでAの平均値とBの平均値を求めてデータセットに出力したいとします。
これはOUTPUTステートメントに以下の書き方をするだけでokです。

proc summary data=DT1;
   output out=OUT1  mean(A)=A_MEAN  mean(B)=B_MEAN;
run;



構文

OUTPUT OUT=出力データセット名  統計量( 対象変数 ) = 出力変数名 ・・・;



MEANSプロシジャでも同じ書き方が出来るけど、、

proc means data=DT1 noprint;
   output out=OUT1  mean(A)=A_MEAN  mean(B)=B_MEAN;
run;


「MEANS vs SUMMARYプロシジャ」で解説した通り、

MEANSプロシジャでは「VARステートメントを省略すると、CLASSステートメント等のその他のステートメントに指定していない全ての数値変数」が裏で集計されているようで、

SUMMARYプロシジャの方が、余計な集計が行われないし、短い文で書けるので効率的です。


2015年7月29日水曜日

MEANS vs SUMMARYプロシジャ



大人しく控え目な性格のSUMMARYプロシジャは、MEANSプロシジャの影に隠れがちです。
この2つは、ほとんど同じ挙動をしますが、ほんのちょっと違います。


サンプルデータ
data DT1;
input A B;
cards;
1 125
2 10
3 20
;



違い①

以下はMEANS と SUMMARYプロシジャによる実行結果ですが、同じ結果が得られます。

proc means data=DT1 ;
   var A;
run;

proc summary data=DT1 print;
   var A;
run;




異なる点として、SUMMARYプロシジャは「PRINTオプション」を付けないと集計結果が画面に表示されません。

proc summary data=DT1 ;
   var A;
run;

ログ
ERROR: PRINTオプションまたはOUTPUTステートメントがありません。
NOTE: エラーが発生したため、このステップの処理を中止しました。



違い②

以下はVARステートメントを省略した場合の集計結果です。

proc means data=DT1 ;
run;







proc summary data=DT1 print;
run;


VARステートメントを省略すると、、
  • MEANSプロシジャ: CLASSステートメント等、その他のステートメントに指定していない全ての数値変数が集計される。
  • SUMMARYプロシジャ: OBS数が算出される。

SUMMARYプロシジャの方が全体的に最小限の動きしかしていない感じでですね。
まずは今回紹介した性質の違いを覚えておきましょう。



SUMMARYプロシジャが役に立つ例




2015年7月28日火曜日

MEANSまたはSUMMARYプロシジャで使えるIDGROUPオプションの紹介


最近のお気に入りオプションなので紹介したいと思います。

サンプルデータ
data DT1;
input A B$;
cards;
2 aa
1 bb
3 cc
2 dd
. ee
;

サンプルに対して以下のプログラムを実行すると、、
proc summary data=DT1;
   output out=OUT1 idgroup( max(A) out[5] (A B)= );
run;

なんか横一行のデータが出来ました。

IDGROUPオプションの中に注目してみましょう。
「max(A) out[5] (A B)=」 で変数Aが大きい順に行を並べ、上位5行のAとBの値をそれぞれ横に転置して表示するようなイメージです。

大きい順で同値がある場合(今回の例では、1行目と4行目のAが両方2)、オブザベーションの並び順で参照していきます(1行目、4行目の順で参照していく)。


注意点1
上の例で「max(A)」だけだとAが欠損値のオブザベーションは選択されません(今回の例では5行目)
欠損値のやつも引っ張ってきたい場合、以下の通りmissingオプションを追加します。

proc summary data=DT1;
   output out=OUT1 idgroup( max(A) missing out[5] (A B)= );
run;

また「min(A)」とすれば変数Aが小さい順になります。


注意点2
制限として1つの変数につき横に並べられるのは100個までのようです。

2015年3月23日月曜日

PROC MEANSの、COMPLETETYPES・PRELOADFMTオプションの紹介



注意点もあるので最後までご覧ください。
まずは以下のプログラムと結果を見てみましょう。

*** サンプルデータ作成 ;
data DT1;
input A B;
cards;
1 10
1 20
3 30
3 40
3 50
;
 A 
B
  1  
  10 
  1
  20 
  3
  30
  3
  40  
  3
  50  

*** FORMAT作成 ;
proc format;
   value MYFMT
   1 = "aaa"
   2 = "bbb"
   3 = "ccc"
 ;
run;

*** Bの要約統計量を、Aの値毎に出す ;
proc means data=DT1 nway;
   var  B;
   class  A;
   format  A  MYFMT. ;
run;



Bの要約統計量を、Aの値毎に出しています。
その際、Aに以下のフォーマットをあてています。
「1="aaa"」「2="bbb"」「3="ccc"」


OUTPUTを見てみると、「2="bbb"」の要約統計量が出てませんね。
これはデータセットDT1のAに「2="bbb"」の値が存在しないからです。


そこで、以下のように completetypes と preloadfmt オプションを使って再度実行してみると、フォーマットに存在するカテゴリ値をすべて出力してくれます。


proc means data=DT1 nway completetypes;
   var  B;
   class  A / preloadfmt ;
   format  A  MYFMT.;
run;




注意点その1

集計対象が0オブザベーションの場合、今回のオプションは機能しません。



注意点その2

以下のようにフォーマットに欠損値を定義して、MEANSの結果に欠損値のカテゴリも出したい場合、MEANSプロシジャでmissingオプションをつけないと出てくれません。

proc format;
   value MYFMT
   . = "Unknown"
   1 = "aaa"
   2 = "bbb"
   3 = "ccc"
 ;
run;

proc means data=DT1 nway completetypes;
   var  B;
   class  A / missing preloadfmt ;
   format  A  MYFMT.;
run;



注意点その3

以下リファレンスのMEANSプロシジャのCLASSステートメントのページで「PRELOADFMT」>「Interaction」の欄に気になる記述が。


CLASSが文字変数だと、非常に低いまたは高い「sentinel values」が生成されるかも、だそうです。
「sentinel value」はプログラミング用語で「番兵」とかって表現される特別な値らしいです。
SASの内部処理の話なので、ちょっと分かりづらいですね。


SASのテクニカルサポートにも聞いてみました。
聞いてみたうえで、やはり内部的な話なので、ハッキリと分かったわけではないんですが、

こう書いたとき結果がおかしくなるっていう例を以下に示します。

proc format;
   value $x
      "x" - high = "xx"
   ;
run;

data DT2;
   length x $40.;
   x = "x";
   y = 1;
run;

proc means data=DT2 nway completetypes noprint;
   var y;
   class x / preloadfmt;
   format x $x.;
   output out=OUT1 n= mean= / autoname;
run;

OUT1(SAS Ondemand for Academicsで開いたときの画面です)😟


おかしいです。
上の例では、まずFORMATプロシジャの「high」に対する「sentinel value」がカテゴリとして扱われてしまうようです。

この「sentinel value」ですが、上の結果のイメージではxの2行目のところで「?」と出ていて、これはSASのセッションエンコーディングで有効な文字ではないため。

上の結果のイメージは、SAS Ondemand for Academicsで見たときのものです。
他の環境によっては、使用しているSASのセッションエンコーディングで有効な文字ではない場合に、見た目上は欠損値に見えるので、余計混乱のもとになりそうです。

あと、色々試してみましたが、この問題に起因した問題がまだあるような気がしました。
ひとまず、こういう使い方をする場合は注意が必要そうです。そもそもリファレンスにこの事について記載されてるってことはバグではなく仕様ってことなんでしょうか。修正してほしい。。



2014年4月28日月曜日

MEANSプロシジャで結果ビューアに出る結果と同じ形のデータセットを作る。



SAS9.3からMEANSプロシジャに「STACKODSOUTPUT (STACKODS でも可)」というオプションが追加されました。
これは結果ビューアの出力と似た形のデータセットを作ることが出来るオプションです。




サンプルデータ作成

data DT1;
input SEX  HEI  WEI;
cards;
1 165 70
1 155 50
2 160 40
2 150 50
2 149 60
;




3つのデータセット出力方法

STACKODSとそれ以外の出力方法もあわせて紹介していきます。


方法1 ・・・ OUTPUTステートメント
proc means data=DT1 n mean  nway;
   var  HEI  WEI;
   class  SEX / missing;
   output  out=SUM  n= mean= / autoname;
run;

データセットSUM
SEX _TYPE_ _FREQ_ HEI_N WEI_N HEI_Mean WEI_Mean
1 1 2 2 2 160 60
2 1 3 3 3 153 50



方法2 ・・・ ODS OUTPUT
ods output summary=SUM2;
proc means data=DT1 n mean  nway;
   var  HEI  WEI;
   class  SEX / missing ;
run;
ods output close;

データセットSUM2
SEX  NObs VName_HEI  HEI_N  HEI_Mean  VName_WEI  WEI_N  WEI_Mean 
1 2 HEI 2 160 WEI 2 60
2 3 HEI 3 153 WEI 3 50



方法3 ・・・ ODS OUTPUTとSTACKODSの組み合わせ (SAS9.3から)
ods output summary=SUM3;
proc means data=DT1 n mean  nway  STACKODS ;
   var  HEI  WEI;
   class  SEX / missing ;
run;
ods output close;

結果ビューアの出力











データセットSUM3
SEX NObs _control_ Variable N Mean
1 2 HEI 2 160.000000
1 2 WEI 2 60.000000
2 3 1 HEI 3 153.000000
2 3 WEI 3 50.000000




要望としては、将来他のプロシジャでも対応してほしいですね。
FREQプロシジャとか。。