---
title: CLASSDATA集計の薦め
tags:  #[第3回大阪sas勉強会]  
author: [森岡裕[SASユーザー総会世話人]](https://convert.docswell.com/user/6484025)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/L71K3GX4EG.jpg?width=480
description: [第3回大阪sas勉強会] 森岡裕
published: March 31, 24
canonical: https://convert.docswell.com/s/6484025/5YW3W4-2024-03-31-110356
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/L71K3GX4EG.jpg)

CLASSDATA集計の薦め
私，ゼロ埋めしないので
森岡
裕


# Page. 2

![Page Image](https://bcdn.docswell.com/page/G7WDPKNZE2.jpg)

お・こ・と・わ・り
本発表は，発表者個人の責任で，いかなるものも代表しません．
内容は発表者の偏見にまみれています．
一般的な見解ではなく，
とにかく偏った美意識に基づくものだと予めご了承ください．


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4JZGKZ3L73.jpg)

主旨
ダミーデータセットをマージして，ゼロ埋めすることは正しくない


# Page. 4

![Page Image](https://bcdn.docswell.com/page/YE6YQZXMJV.jpg)

使用するテストデータ
→グループ別カテゴリー別に要約統計量と検査値が４超の割合を算出する
data test;
group=1;category=1;VAL=1;output;
group=1;category=1;VAL=2;output;
group=1;category=1;VAL=3;output;
group=1;category=2;VAL=4;output;
group=1;category=2;VAL=5;output;
group=1;category=3;VAL=6;output;
group=1;category=3;VAL=7;output;
group=3;category=2;VAL=8;output;
group=3;category=2;VAL=9;output;
group=3;category=2;VAL=1;output;
group=3;category=2;VAL=2;output;
group=3;category=3;VAL=5;output;
run;
data test;
set test;
FN=VAL&gt;4;
run;
グループ(group)：1,2,3
カテゴリー(category)：1,2,3


# Page. 5

![Page Image](https://bcdn.docswell.com/page/GE5GRWXQE4.jpg)

普通に書けば，以下のような感じですかね
proc summary data=test nway;
class group category;
var VAL FN;
output out=out1_1(drop=_TYPE_ _FREQ_)
n= mean= std= lclm= uclm= min= median=
run;
max= sum= /autoname;
data out1_2;
length group category 8. N FN FPER MEAN CLM STD CLM MIN MEDIAN MAX $15.;
set out1_1;
N = cats(VAL_N);
FN=cats(FN_SUM);
FPER=put(round(divide(FN_SUM,VAL_N)*100,0.1),8.1 -L);
MEAN = put(round(VAL_Mean,0.1),8.1 -L);
if ^missing(VAL_StdDev) then
STD = put(round(VAL_StdDev,0.01),8.2 -L);
else STD=&quot;-&quot;;
if n(VAL_lclm,VAL_uclm)=2 then
CLM=catx(&quot; , &quot;,put(round(VAL_lclm,0.1),8.1),put(round(VAL_uclm,0.1),8.1));
else CLM=&quot;-&quot;;
MIN=cats(VAL_Min);
MEDIAN=put(VAL_MEDIAN,8.1 -L);
MAX=cats(VAL_Max);
keep group--MAX;
run;


# Page. 6

![Page Image](https://bcdn.docswell.com/page/972YDQXW7R.jpg)

当然，元のデータに存在する水準でしか集計されない
一例のため，STDと平均の信頼区間は算出不能


# Page. 7

![Page Image](https://bcdn.docswell.com/page/DJYG2W89JM.jpg)

データに存在しなくても，規定の水準で集計結果を表示したい


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V7NG89QDE8.jpg)

data dummy;
do group=1 to 3;
do category=1 to 3;
output;
end;
end;
run;
data out2_1;
merge dummy
out1_2;
by group category;
run;
よく見るのが，dummyで全水準を持ったレイアウ
トデータセットを作って，それにマージする方法．
あとは，内容に応じて０やハイフンを代入する


# Page. 9

![Page Image](https://bcdn.docswell.com/page/YJ9WK2D8J3.jpg)

data out2_2;
set out2_1;
array zero N FN;
do over zero;
zero=coalescec(zero,&quot;0&quot;);
end;
array hy FPER--MAX;
do over hy;
hy=coalescec(hy,&quot;-&quot;);
end;
run;


# Page. 10

![Page Image](https://bcdn.docswell.com/page/GJ8NR53ZED.jpg)

気に食わない．私はこのやり方が気に食わない．
実際に集計していないのに，あとから欠損を0に変換して
体裁をごまかしているだけ．
データがないならないで，その水準で集計して，きちんとn=0という結
果を得るべきである．
結果は同じでも，正しい道を歩むべきである


# Page. 11

![Page Image](https://bcdn.docswell.com/page/LJLPKYV1ER.jpg)

data clds;
do group=1 to 3;
do category=1 to 3;
output;
end;
end;
run;
proc summary data=test classdata=clds nway;
class group category;
var VAL FN;
output out=out3_1(drop=_TYPE_ _FREQ_)
n= mean= std= lclm= uclm= min= median=
run;
max= sum= /autoname;


# Page. 12

![Page Image](https://bcdn.docswell.com/page/47M42NG5EW.jpg)

dummyを作ってマージするのと似たようなもんじゃないかと思うかもし
れないけども．
きちんと与えられた水準で集計することで，０とするべきものにはきち
んと0が入り，算出不能なもののみが欠損となる
→あとは全ての値について欠損をハイフンに変えるだけでよい．
→余計な忖度が入らないので，ミスが起きない


# Page. 13

![Page Image](https://bcdn.docswell.com/page/P7RWMDZZE9.jpg)

data wk1;
set adam.adae
adam.adae(in=ina) end=eof;
where saffl=&quot;Y&quot;;
where same anl01fl=&quot;Y&quot;;
if ina then trtan=4;
AEの事象別集計のように水準が確定しないものについても応用ができる．
多群の試験において，いずれかの群にのみ生じた事象はその他の群では
度数0になるということなので，群を問わずに発生した事象をユニークに
したデータセットを作成し，それを群で倍化重複してクラスデータに
すればよい
/*SOCクラスデータをhashで作成*/
if _N_=1 then do;
declare hash soc();
soc.definekey(&quot;AEBDSYCD&quot;,&quot;AEBODSYS&quot;);
soc.definedone();
end;
/*PTクラスデータをhashで作成*/
if _N_=1 then do;
declare hash pt();
pt.definekey(&quot;AEPTCD&quot;,&quot;AEDECOD&quot;,&quot;AEBDSYCD&quot;);
pt.definedone();
end;
soc.ref();
pt.ref();
if eof then do;
soc.output(dataset:&quot;_soc_class&quot;);
pt.output(dataset:&quot;_pt_class&quot;);
end;
run;
data soc_class;
set _soc_class;
do TRTAN=1 to 4;
output;
end;
run;
data pt_class;
set _pt_class;
do TRTAN=1 to 4;
output;
end;
run;


# Page. 14

![Page Image](https://bcdn.docswell.com/page/PJXPV191EX.jpg)

/*soc例数集計*/
proc sort data=wk1 out=_wk1 nodupkey;
by USUBJID TRTAN AEBDSYCD AEBODSYS ;
run;
proc summary data=_wk1
classdata=soc_class
nway exclusive ;
class TRTAN AEBDSYCD AEBODSYS ;
var TRTAN;
output out=soc_1(drop=_TYPE_ _FREQ_)
n=count ;
run;
/*soc件数集計*/
proc summary data=wk1
classdata=soc_class
nway exclusive ;
class TRTAN AEBDSYCD AEBODSYS ;
var TRTAN;
output out=esoc_1(drop=_TYPE_ _FREQ_)
n=ecount ;
run;


# Page. 15

![Page Image](https://bcdn.docswell.com/page/3JKDQ2PM7D.jpg)

水準が動的な解析については，ハッシュオブジェクトで何か処置のつい
でにクラスデータを作成しておき，それでsummaryするのが私の定跡
文句があるならかかってこい！！


# Page. 16

![Page Image](https://bcdn.docswell.com/page/LE3RP4X275.jpg)

ご清聴ありがとうございました


