Datensatz aus Datensatz erzeugen

Hallo,
ich hab einen großen Datensatz und würd gern einen kleinen daraus machen.
Blöderweise nicht nur kleiner, sondern auch anders angeordnet.

Der Originaldatensatz hat folgende Variablen:
Bundesland, Geschlecht, Alter in 5y-Gruppen
Jede Person bildet eine Zeile

Der neue Datensatz soll folgende Variablen haben:
Bundesland, Geschlecht, Alter 0-4 Jahre, Alter 5-9 Jahre, Alter 10-14 Jahre,..., Alter 85 und älter
jede Kombination aus Bundesland und Geschlecht bildet eine Zeile, in den Altersvariablen stehen die Häufigkeiten.

Ich hab eine neue Altersvariable (Gruppen) gebildet und mit proc tabulate eine Tabelle erstellt, die so auschaut wie oben beschrieben. Wenn ich in die proc tabulate ein out reinnehm, schaut der Datensatz aber ganz anders aus als die Tabelle. Wie kann ich das hinkriegen? Ich hoffe, ich hab halbwegs verständlich erklärt was ich machen will.

Danke, M

selbes Thema, neues Problem

Hallo,
ich hab den Datensatz so wie Jan es beschrieben hat erzeugt und war damit sehr zufrieden.
Im Lauf der Berechnungen hat sich aber ein neues Problem ergeben.

Wenn ich in die proc format vor geschlecht oder bundesland ein ALL schreib, hab ich gleich auch Werte für beide Geschlechter zusammen bzw. für Österreich. Es ergibt einen fehlenden Wert, den ich dann im Datensatz leicht durch 3 bzw. 10 ersetzen kann.

Ich hab allerdings auch eine Variable der ich in der proc format ein Format zuweise (so hat sie etwa 15 Ausprägungen statt 100). Für diese Variable ergibt das ALL keine eigenen Zeilen im Datensatz. Wenn ich die Formatierung weglasse würds schon gehen, so kann ich es aber nicht brauchen. Gibts da eine praktikable Lösung oder muss ich wirklich eine neue Variabel bilden der ich dann kein Format zuweise?

Hallo Monika, kannst Du mal

Hallo Monika,

kannst Du mal einen Beispieldatensatz und deinen Code hinzufügen, damit man das Problem erkennen kann?

Schöne Grüße

Jan

Beispiel

Hallo,
leider bin ich so ein sas-Würschtl, dass ich keinen Beispieldatensatz erstellen kann, aber hier der Kode, vielleicht reicht der ja auch...

PROC TABULATE DATA=library.dbabzug_20090224151933431 OUT=work.temp;
FORMAT KRE_icd10_3 $rvza_ku.;
CLASS KRE_bj KRE_bdl KRE_GESCHL KRE_icd10_3 KRE_ALTKREGR;
TABLE ((KRE_GESCHL all)*(KRE_bj)*(KRE_bdl all)*(KRE_icd10_3 all)),((KRE_ALTKREGR)*(N))/PRINTMISS;
WHERE 1983<=KRE_bj<=2006 and KRE_icd10_3<'D00' and KRE_icd10_3~='C44' and ((KRE_STDGROB=7 and STF_KRETOD~=.) or KRE_STDGROB~=7);
RUN;

DATA work.temp;
SET work.temp;
IF KRE_bdl=. THEN KRE_bdl=10;
IF KRE_GESCHL=. THEN KRE_GESCHL=3;
RUN;

mit dem Datensatz geh ich dann in die proc transpose, alles weitere funktioniert dann auch nach Plan...

Hallo Monika,

Hallo Monika,

ich kann dein Problem nicht nachvollziehen. Wenn ich einen Datensatz mit deinen Variablen durchlaufen lasse erhalte ich auch für "KRE_icd10_3" Datensätze mit Missings.
Das ist völlig unabhängig davon, ob ich "KRE_icd10_3" formatiere oder nicht. In deinen Programmcode musst du aber noch eine Zeile einfügen.

DATA work.temp;
SET work.temp;
IF MISSING(KRE_bdl) THEN KRE_bdl = 10;
IF MISSING(KRE_GESCHL) THEN KRE_GESCHL = 3;
IF MISSING(KRE_icd10_3) THEN KRE_icd10_3 = "D00";
RUN;

Die fehlenden Werte abfragen, kannst du aber nur, wenn fehlende Werte keine gültige Kategorie sind. Die ALL-zeilen kannst du an der Variable "_TYPE_" erkennen. Besser wäre es so zu formulieren.

DATA Work.Temp;
SET work.temp;
IF SUBSTR(_TYPE_,3,1) = "0" THEN KRE_GESCHL = 3;
IF SUBSTR(_TYPE_,2,1) = "0" THEN KRE_bdl = 10;
IF SUBSTR(_TYPE_,4,1) = "0" THEN KRE_icd10_3 = "D00";
RUN;

In "_TYPE_" steht für jede Kategorie eine 1 oder 0, je nachdem, ob es sich um eine ALL-zeile handelt oder nicht. Die Reihenfolge in "_TYPE_" richtet sich nach der Reihenfolge, in der die Kategorien in CLASS-Statements erscheinen.

Schöne Grüße

Jan

Leider nein

Hallo Jan,
diesmal hauts leider nicht hin.
Nach wie vor - unformatiert gehts, formatiert nicht.

... und ich hab auch keine Variable _TYPE_

Mein Datensatz hat nachher folgende Variablen:
die, die auch in der Tabelle vorkommen - Berichtsjahr, Bundesland, Geschlecht, ICD10_3, Alter
und dann noch - Beobachtungstyp, Seite für Beobachtung, Tabelle für Beobachtung, N

Testdatensatz

Hallo Jan,
ich hab jetzt im Editor einen Minidatensatz "ähnlich" meinem gebastelt und stell die ganze Einlesesyntax dazu und alles was sonst vielleicht noch weiterhilft...

Es muss irgendwie am Format liegen. Ich hab auch andere Formate erstellt - wobei ich meins kopiert und dann geändert hab, also sollten sie sich eigentlich nicht grundsätzlich unterscheiden.
Nehme ich mein urspüngliches Format, steht in der Variable KRE_icd10_3 der Text den ich im Format zuweise. Dann hab ich keine missings.
Nehm ich das neue Format (wobei ich keinen grundsätzlichen Unterschied erkenne), steht in der Variable KRE_icd10_3 der Wert aus der Variable. Wenn ich mehreren Werten dasselbe Format zuweise, steht immer der erste Wert der in diesem Format vorkommt. in der Tabelle steht der Text des formats so wie es sein soll. Soweit sogut, und dann gehts auch, dann kommen missings!

Ich blick da nicht mehr durch ;(

Datensatz test.txt
1 3 C02 1999 2
2 1 C02 2002 6
1 2 C04 2002 14
2 4 C77 2000 14
2 3 C87 1998 13
2 4 C44 1988 14
2 3 C02 1987 17
2 2 C02 2000 5
2 3 C87 1998 7
2 4 C44 1988 7

Einlesen

FILENAME a ('Pfad\test.TXT');

DATA work.test;
INFILE a TRUNCOVER;
INPUT
@1 KRE_GESCHL 1.
@3 KRE_bdl 1.
@5 KRE_icd10_3 $3.
@9 KRE_bj 4.
@14 KRE_ALTKREGR 2.
;
run;

Tabelle bilden

PROC TABULATE DATA=work.test OUT=work.temp;
*FORMAT KRE_icd10_3 $rvza_ku.;
CLASS KRE_bj KRE_bdl KRE_GESCHL KRE_icd10_3 KRE_altkregr;
TABLE ((KRE_GESCHL all)*(KRE_bj)*(KRE_bdl all)*(KRE_icd10_3 all)),((KRE_altkregr)*(N));
RUN;

mein ursprüngliches Format

proc format;
value $RVZA_ku
C00-C10='C00-C10 & C31-C32, Kopf & Hals'
C15='C15, Speiseröhre'
C16='C16, Magen'
C18-C21='C18-C21, Dickdarm & Enddarm'
C22='C22, Leber'
C25='C25, Bauchspeicheldrüse'
C31-C32='C00-C10 & C31-C32, Kopf & Hals'
C33-C34='C33-C34, Luftröhre & Bronchien & Lunge'
C43='C43, Bösartiges Melanom der Haut'
C50='C50, Brust'
C53='C53, Gebärmutterhals'
C54-C55='C54-C55, Gebärmutterkörper & Gebärmutter n.n.bez.'
C56='C56, Eierstock'
C61='C61, Prostata'
C62='C62, Hoden'
C64='C64, Niere'
C67='C67, Harnblase'
C70-C72='C70-C72, Gehirn & Zentralnervensystem'
C73='C73, Schilddrüse'
C81='C81, Hodgkin'
C82-C85='C82-C85,C96, Non-Hodgkin'
C96='C82-C85,C96, Non-Hodgkin'
C90='C90, Plasmozytom'
C91-C95='C91-C95, Leukämie'
other='Rest: Andere und nicht näher bezeichnete bösartige Neubildungen';
run;

die Testformate

proc format;
value $RVZA_test
C02='C00-C10 & C31-C32, Kopf & Hals'
C04='C00-C10 & C31-C32, Kopf & Hals'
C44='C44, sonst. Haut'
C77='C77, Lymph'
C87='C87, gibts nicht'
;

proc format;
value $RVZA_testneu
C44='C44, sonst. Haut'
C77='C77, Lymph'
C87='C87, gibts nicht'
other='rest'
;
run;

Missing Value auch formatieren

Hallo Monika,

jetzt ist mir der Fehler klar geworden.
1)
In der Formatdefinition hast du die Definition other verwendet. Demnach wird jeder Wert, der in den vorangegangenen Zuweisungen nicht vorkommt, mit diesem Wertlabel versehen. Auch die Missing Values.
2)
Die Variable _TYPE_ kommt in deinem Ergebnisdatensatz vor, aber du hast sie nicht erkannt, da sie das Label "Type of Observation" hat. Wenn du dir die Werte in der Tabellenansicht anschaust, kannst du einstellen, ob du die Label oder die Variablennamen siehst.
Unter "View->Column Names" kannst du dir die Variablennamenansicht einstellen.
Proc Print liefert dir ebenfalls die Spaltennamen.

Du musst also in der Formatdefinition eine Zeile einfügen.

proc format;
value $RVZA_ku
...
'C91'-'C95' = 'C91-C95, Leukämie'
' ' = [$3.]
other = 'Rest: Andere und nicht näher bezeichnete bösartige Neubildungen';
;
RUN;

Schöne Grüße

Jan

Teilweise

Hallo Jan,
ich habs zwar erst nicht verstanden, weil ich im urspünglichen Datensatz ja keine Missings hab. Dass sich das Format dann noch auf die Tabellenwerte auswirkt war mir nicht klar.
Also bin ich mal deinen Anweisungen gefolgt:
1) format geändert
2) _TYPE_ gesucht und gefunden
3) 0 und 1 in _TYPE_ verstanden
4) Datenstatz erstellt - und siehe da - für die All Zeilen bei der Vatiable KRE_icd10_3 hatte ich plötzlich missings in der Variable.

und dann kam das nächste Problem:
zur Info: Ich hab im CLASS die KRE_icd10_3 an die letzte Stelle gegeben, der Übersichtlichkeit halber.

DATA Work.Temp;
SET work.temp;
IF SUBSTR(_TYPE_,3,1) = "0" THEN KRE_GESCHL = 3;
IF SUBSTR(_TYPE_,2,1) = "0" THEN KRE_bdl = 10;
IF SUBSTR(_TYPE_,5,1) = "0" THEN KRE_icd10_3 = "Zusammen";
RUN;

... und dann schau ich wieder in meinen Datensatz und hab in den schönen vormals leeren Feldern wieder den Text zum "REST..." drinnen. Bitte warum denn das wieder und was tu ich dagegen??

Schöne Grüße und vielen Dank für deine Geduld,
Monika

PS: Ich hab bei meinen Formaten die Werte nicht unter Hochkomma sondern nur den zugewiesenen Text, wäre das sinnvoll oder ist das egal?

Hallo Monika, mit der

Hallo Monika,

mit der Programmzeile

IF SUBSTR(_TYPE_,5,1) = "0" THEN KRE_icd10_3 = "Zusammen";

weist Du der Variablen KRE_icd10_3 den Wert "Zus" zu.
"Zus", weil die Variable laut Deiner vorherigen Definition, nur 3 Zeichen hat. "Zus" fällt allerdings in der Formatdefinition wieder unter OTHER. Entweder definierst Du Dir einen Wert in dem Format, der als Wertlabel "Zusammen" bekommt, und weist im obigen Statement diesen Wert der Variable zu oder Du verzichtest auf die Definition von OTHER und weist die Restkategorie explizit den möglichen Werten zu. Wenn Du dies tust, werden alle Werte, für die Du keine Definition erstellt hast mit ihren Werten angezeigt, wie sie im Datensatz stehen. Dadurch behältst Du besser den Überblick, welche Werte denn wirklich vorkommen. Am besten ist, Du machst beides.

Zu den Hochkommas.
Bei den Werten, die Du hast, geht das so, wie Du es machst Aber schon bei der Definition des Missing Value brauchst Du die Hochkommas, ebenso bräuchtest Du die Hochkommas wenn Du z. B. Umlaute, Bindestriche, Leerzeichen, etc. in Deinen Werten hättest. Ich definiere Character-Formate immer mit Hochkomma oder Anführungszeichen, auch wenn das ein bisschen lästig ist.

Schöne Grüße

Jan

Super passt, aber ich verstehs nicht ganz

Hallo Jan,
ganz ganz lieben Dank nun klappts endlich.

Eine Bitte um eine Erklärung hätte ich aber noch. Ich hab das mit den Formaten noch nicht so ganz kapiert.
Wenn ich meinen urspürunglichen Datensatz anschau, hab ich dort immer die echten Werte drinnen stehen. Auch nachdem ich im Rahmen einer Proc Tabulate Formate zugewiesen habe. Wenn ich aber den TEMP Datensatz erzeuge, hab ich immer in der KRE_icd10_3 die Labels angezeigt.
Ist das nur eine Anzeigesache und kann ich das ausstellen, oder werden meine ursprünglichen Werte ersetzt, kann ja eigenltich gar nicht sein?

LG, Monika

Formate Anschauungssache

Hallo Monika,

eigentlich sind Formate nur Anschauungssache. Du kannst die ursprüngliche Ansich wiederherstellen, in dem Du z. B. schreibst:

DATA ohneformat;
FORMAT KRE_icd10_3 $3.;
SET mitformat;
RUN;

Oder jede andere Ansicht, indem Du das Format wechselts. Du kannst Daten in verschiedenen Gruppen zusammenfassen und auswerten, ohne die Ursprungsdaten zu verändern.
Anders ist es, wenn Du Formate zum Gruppieren der Daten benutzt und in eine Tabelle ausgibst. Es stehen dann in den Ergebnistabellen nur noch Platzhalter, also ein Wert aus der Gruppe, der das richtige Wertlabel hat. Wenn du das nicht willst, musst Du deine Werte mit

neuerwert = PUT(KRE_icd10_3, $RVZA_ku.);

umwandeln.

Schöne Grüße

Jan

Danke

Super, jetzt kommt Licht in die Sache.
LG, Monika

PROC TABULATE und PROC TRANSPOSE

Hallo,

das geht z. B. mit PROC TABULATE und PROC TRANSPOSE.

PROC TABULATE
DATA = Quelle
OUT = temp
;
CLASS Bundesland Geschlecht Alter;
TABLE
Bundesland * Geschlecht,
Alter * N/
PRINTMISS
;
RUN;

PROC TRANSPOSE
DATA = temp
OUT = Ziel
;
BY Bundesland Geschlecht;
ID Alter;
VAR N;
RUN;

PROC DELETE DATA = temp; RUN;

Schöne Grüße

Jan

Danke

Hallo Jan,
was tät ich nur ohne dich...