Kreuztabelle als Data-Set so wie aus proc tabulate
Hallo zusammen,
mit dem proc tabulate kann man bekanntlich wunderschön Kreuztabellen erzeugen. Aber wie kann man die schöne Ausgabe als Data Set erhalten?
Und zwar genau so wie im OUT-Fenster! Also nicht so wie z.B. die Ausgabe aus dem proc means.
Beispiel Ausgabe aus proc tabulate:
Kreuztabelle ('tabulate', je mm-Wert eine Spalte mit 'Sum(ww)')
------------------------------
| | Monat |
| |--------------------|
| | m1 | m2 | m3 |
| |------+------+------|
| | Wert | Wert | Wert |
| |------+------+------|
| |Summe |Summe |Summe |
|-------+------+------+------|
|Filiale| | | |
|-------| | | |
|f1 | 3,00| 4,00| 3,00|
|-------+------+------+------|
|f2 | 23,00| 66,00| 67,00|
|-------+------+------+------|
|f3 |996,00|443,00|1330,0|
------------------------------
Wunsch-Data-Set, Ausgabe mit proc print:
Obs ff m1 m2 m3 1 f1 3 4 3 2 f2 23 66 67 3 f3 996 443 1330
Mit dem ODS oder dem out= im PROC-Statement kommt man m.E. nicht zum Ziel. Damit entsteht nur ein unschönes Data Set (Bespiel mit proc tabulate ... out=):
Obs ff mm ww_Sum 1 f1 m1 3 2 f1 m2 4 3 f1 m3 3 4 f2 m1 23 5 f2 m2 66 6 f2 m3 67 7 f3 m1 996 8 f3 m2 443 9 f3 m3 1330
Erste Frage: Geht das?
Zweite Frage: Wie geht das wenn man doppel- oder dreifach-Spalten je mm-Wert hat?
Beispiel für dreifach-Spalten: sum(ww) mean(ww) und n(ww).
Eine umständliche Variante habe ich auch schon (s.u.), aber die gefällt mir nicht! Es muss doch auch einfach gehen.
Aber wie???
Das war sozusagen die Einleitung, jetzt kommt die "Lang-Version" mit Beispiel-Daten, Beispiel-Code und allem drum und dran.
Beispiel-Code :
input ff $2. mm $2. ww;
cards;
f1m10
f1m11
f1m12
f1m21
f1m23
f1m33
f2m111
f2m112
f2m221
f2m222
f2m223
f2m333
f2m334
f3m1331
f3m1332
f3m1333
f3m2221
f3m2222
f3m3331
f3m3332
f3m3333
f3m3334
;
run;
title2 "Kreuztabelle ('tabulate', je mm-Wert eine Spalte mit 'Sum(ww)')";
options linesize=80;
PROC TABULATE DATA=tmp_SD0;
CLASS ff mm; /* Gruppierungs-Variablen */
VAR ww; /* ww ist für Zellen-Summe */
TABLE
ff /* "runter" */
,
mm *(ww*SUM*f=commax6.2) /* "quer", je mm-Wert eine Spalte */
/ rts=9 /* rts == RowTableSize */
/* == Breite d.TextSpalte */
;
keylabel SUM='Summe';
label
ff='Filiale'
mm='Monat'
ww='Wert'
;
RUN;
Wie kann man diese schöne Ausgabe als Data Set erhalten? Und zwar genau so wie im OUT-Fenster! Also nicht so:
Obs ff mm ww_Sum 1 f1 m1 3 2 f1 m2 4 3 f1 m3 3 4 f2 m1 23 5 f2 m2 66 6 f2 m3 67 7 f3 m1 996 8 f3 m2 443 9 f3 m3 1330
sondern so
Obs ff m1 m2 m3 1 f1 3 4 3 2 f2 23 66 67 3 f3 996 443 1330
Gefunden bzw. ausgetüfftelt habe ich bisher eine proc tabulate... out= mit proc transpose-Lösung. Meine Lösung ist so:
CLASS ff mm; /* Gruppierungs-Variablen */
VAR ww; /* ww ist für Zellen-Summe */
TABLE
ff /* "runter" */
,
mm *(ww*SUM*f=commax6.2) /* "quer", je mm-Wert eine Spalte */
/ rts=9 /* rts == RowTableSize */
;
keylabel SUM='Summe';
label
ff='Filiale'
mm='Monat'
ww='Wert'
;
RUN;
proc transpose data=tmp_SD1 out=tmp_SD3(drop=_name_);
by ff;
id mm;
run;
title2 "Kreuztabelle als Data-Set wie aus proc tabulate ";
title3 " (Kreuztabelle je mm-Wert eine Spalte mit 'Sum(ww)')";
proc print data=tmp_SD3;
run;
Zweite Frage (s.o.): Wie geht das wenn doppel- oder dreifach-Spalten je mm-Wert hat?
Beispiel für dreifach-Spalten: sum(ww) mean(ww) und n(ww).
Die umständliche Variante (s.u.) gefällt mir ganz und gar nicht! Es muss doch auch besser gehen, z.B. mit einem proc tabulate und einem proc transpose und fertig. Aber wie???
Code der umständlichen Variante:
Der Code steht hier
Ausgabe dazu (Auszug):
Kreuztabelle ('tabulate', je mm-Wert eine Doppel-Spalte mit 'Sum(ww) + Mean(ww)')
---------------------------------------------------
| | Monat |
| |-----------------------------------------|
| | m1 | m2 | m3 |
| |-------------+-------------+-------------|
| | | Wert | | Wert | | Wert |
| | Wert |------| Wert |------| Wert |------|
| |------|Mitte-|------|Mitte-|------|Mitte-|
| |Summe |lwert |Summe |lwert |Summe |lwert |
|-------+------+------+------+------+------+------|
|Filiale| | | | | | |
|-------| | | | | | |
|f1 | 3,00| 1,00| 4,00| 2,00| 3,00| 3,00|
|-------+------+------+------+------+------+------|
|f2 | 23,00| 11,50| 66,00| 22,00| 67,00| 33,50|
|-------+------+------+------+------+------+------|
|f3 |996,00|332,00|443,00|221,50|1330,0|332,50|
---------------------------------------------------
Gesamt-Kreuztabelle als Data-Set wie aus proc tabulate
(Kreuztabelle je mm-Wert eine DoppelSpalte mit 'Sum(ww) + Mean(ww)')
Obs ff sum_m1 sum_m2 sum_m3 mean_m1 mean_m2 mean_m3
1 f1 3 4 3 1.0 2.0 3.0
2 f2 23 66 67 11.5 22.0 33.5
3 f3 996 443 1330 332.0 221.5 332.5
Abgesehen davon, dass die Spalten zu Monat m1, m2, ... nicht mehr als Gruppe zusammen stehen kann man mit der Lösung leben, aber umständlich ist sie schon und schlanker wäre ganz einfach besser!!!
Gruß
Hans Kneilmann, Schäfer Shop GmbH (SSI)
Nachtrag, 16.11.2007: Es geht einfacher, siehe Beitrag unten und siehe 2. Datei im Anhang
