Recodierung

<< Click to Display Table of Contents >>

Navigation:  Datenmodifikation > Variablen und Codes >

Recodierung

Die Funktionalitäten rund um das Statement RECODE ermöglichen die Umkodierung von Variablenwerten bzw. Wertemengen.

Angesprochen werden können einzelne Variablen oder Variablenlisten, mehrere Rekodierungen können in einem Statement vorgenommen sowie Restmengen verarbeitet werden. Recodes können außerdem als Labeleigenschaft, für Variablenfamilien und -gruppen sowie Gruppenvariablen definiert werden. Es können Bedingungen in die Rekodierung einbezogen und mehrere Datenquellen behandelt werden.

Mit RECODELASTWINS wird die Reihenfolge festgelegt, mit der RECODE-Anweisungen abgearbeitet werden. CheckRecode überprüft vorhandene RECODE-Anweisungen auf stimmig definierte Grenzwerte.

Als Variante können mit RANGES in vereinfachter Syntax Wertebereiche rekodiert werden.


Recode

RECODE erlaubt die Umkodierung einzelner Variablenausprägungen der zuletzt definierten Variable oder einer Liste explizit benannter Variablen.

Syntax:

RECODE <recode>  { / <recode> }*n [ ELSE = <number> ] ;

<recode> ::= <valuelist> = < number >
< valuelist > ::= [ <number> | <number> : <number> | <valuelist>

Beispiele:

RECODE 1 2 3 = 3;

Dieses Statement fasst die Ausprägungen 1, 2 und 3 der zuletzt definieren Variable zur Ausprägung 3 zusammen.

RECODE item1 item2 item3 1 = 4;

Dieser Befehl rekodiert die Ausprägung 1 der Variablen item1, item2 und item3.

Auch möglich:

RECODE item1 TO item8 1 = 4;

Mehrere RECODEs

Mehrere RECODEs zu einer Variablen können zusammengefasst werden; einzelne Recodegruppen werden mit dem Schrägstrich (»/«) getrennt. Sollen ganze numerische Bereiche umkodiert werden, so können diese Bereiche mit dem Doppelpunkt angegeben werden.

Beispiel:

RECODE x y z 
1:5 , 7 = 1 / 

6 : 10 = 2 / 
11 : 15 = 3;

Eine Liste von RECODE-Zuweisungen, die durch / getrennt sind, wird nur solange durchsucht, bis ein Match festgestellt wird. Im vorliegenden Fall wird 7 also auf 1 kodiert, obwohl 7 auch im zweiten RECODE-Set enthalten ist. Kommata in der Werteliste sind bedeutungslos; »1,5«, »1 5« und »1, 5« werden identisch interpretiert.

Else

Sollen alle nicht explizit aufgeführten Werte auf einen Rest- oder Defaultwert gesetzt werden, so kann man anstelle eines numerischen Wertes oder Bereichs im letzten Teil der RECODE-Anweisung das Keyword ELSE schreiben. Zum Beispiel:

RECODE x y z 
1:5 = 2 / 
6:10=1 / 
ELSE=99;

RECODEs als Labeleigenschaft

RECODEs können auch als VALUELABEL-Eigenschaft mitgeführt werden.

Diese werden iterativ weiter verfolgt. Zum Beispiel:

singleq xxx = 45 1 
labels

1 "sehr gut"       recode 2

2 "eher gut"       recode 3

3 "teils/teils"    recode 4

4 "eher schlecht"  recode 5

5 "schlecht"

;

Hier werden alle Werte letztlich auf 5 rekodiert: Das ist zwar im Falle z.B. des Codes 1 nicht sehr effizient, weil es in vier Schritten erfolgt, entspricht aber der internen Abarbeitungslogik von GESStabs.

LabelRecode

Voreinstellung zu Nutzung von Recode als Labeloption

Syntax:

LABELRECODE = [ YES | NO ];

Default: NO

LABELRECODE steuert, ob es im Script erlaubt ist, RECODE als Labeloption zu verwenden.

RECODEs in Variablenfamilien und -gruppen

RECODEs dürfen auch auf VARFAMILY und VARGROUP angewandt werden: dann werden alle in der VARGROUP bzw. VARFAMILY zusammengefassten atomaren Variablen rekodiert.

Wenn man z.B. eine Variablengruppe aus 20 Variablen hat

VARGROUP Gruppe = ( item1 TO item20 ) EQ 1;

dann ist

RECODE Gruppe 

3 : 5 = 2;

bedeutungsgleich mit

RECODE item1 TO item20

3 : 5 = 2;

GroupRecode

Mit GROUPRECODE können auch Gruppenvariablen rekodiert werden.

Syntax:

GROUPRECODE <recode>  { / <recode> }*n [ ELSE = <number> ] ;

<recode> ::= <valuelist> = < number >
< valuelist > ::= [ <number> | <number> : <number> | <valuelist>

Die Anweisung

GROUPRECODE GRR 3 = 5 ;

checkt in der dritten Variable der Gruppe, ob sie zutrifft; wenn ja, wird der Wert in dieser Variablen gelöscht, und die fünfte Variable wird auf TRUE gesetzt.

Anstelle des konstanten RECODE-Wertes nach dem Gleichheitszeichen darf auch ein Variablenname einer atomaren Variable stehen.

Bedingungen

RECODEs können auch von einer Bedingung abhängig gemacht werden, z.B.:

IF ( v3 eq 44 ) OR ( 7 IN f5 ) 
RECODE v7 

2=3 / 

4=5 / 

ELSE = 99;

Anstelle des konstanten RECODE-Wertes nach dem Gleichheitszeichen darf auch ein Variablenname einer atomaren Variable stehen.

RECODEs bei mehreren Datenquellen

RECODE-Anweisungen dürfen auch in $-Zeilen in Inputfiles stehen. Diese RECODEs gelten nur für die Fälle innerhalb dieses Files, d.h. sie verlieren am Ende des Files ihre Gültigkeit. Damit können z.B. mehrere Wellen, deren Variablen in unterschiedlichen Inputfiles ggf. an verschiedenen Inputpositionen stehen, auch dann leicht ausgewertet werden, wenn die Variablenausprägungen nicht überall gleich kodiert sind. Am Anfang jeden Files stehen dann die File-spezifischen Spaltenzuweisungen (VARNAME) und die File-spezifischen RECODEs, um die Daten jeweils anzupassen. Jede dieser Zeilen wird mit dem $-Zeichen in Sp. 1 als Anweisungszeile kenntlich gemacht.


Unterstützende Funktionen zu RECODE

RecodeLastWins

Steuerung der sequenziellen Abarbeitung der Recode-Klauseln: Gewinnt das letzte inhaltlich passende RECODE oder das erste?

Syntax:

RECODELASTWINS = [ YES | NO ];

Voreinstellung: NO

RECODELASTWINS legt fest, ob bei Rekodierungen der erste oder der letzte Treffer gültig sein soll. Im Standardfall (RECODELASTWINS = NO;) wird der erste Treffer verwendet. Der Schalter gilt für alle danach stehenden RECODE-Anweisungen, bis zum Scriptende oder bis zur nächsten Setzung mittels RECODELASTWINS.

Zur Erläuterung: Syntaktisch ist es erlaubt, dass RECODE-Anweisungen mehrdeutig sind.

Das ist kein Bug, sondern ein Feature.

Im folgenden Statement

RECODE xx

0  : 10 = 1 /

10 : 15 = 2 /

15 : 9999 = 3

;

sind die Grenzwerte doppelt verwendet. Das Statement ist nichtsdestotrotz eindeutig. RECODEs werden intern sequentiell abgearbeitet. Im Standardfall (RECODELASTWINS = NO;) wird der Scan abgebrochen, wenn ein erster »Treffer« erzielt wurde. Eine 10 würde also auf eine 1 rekodiert werden, obwohl eine 2 auch als »logisch« gelten könnte, da es auch die klausel »10:15=2 gibt.

Die oben stehende RECODE-Anweisung wäre also für Menschen (und in Labels) zu interpretieren als »bis 10«, »über 10 bis 15« etc.

Für Rekodierungen wie "bis unter 10", "10 bis unter 15" etc. war nach bisherigem Syntaxstand (mit Voreinstellung NO)eine Umkehr der Reihenfolge der einzelnen RECODE-Zuweisungen angemessen:

RECODE xx

15 : 9999 = 3 /

10 : 15 = 2 /

0  : 10 = 1

;

In diesem Fall würde die 10 auf die 2 rekodiert werden, da "10 : 15 = 2" vor "0 : 10 = 1" steht. Da es bei vielen Rekodierungen aufwendig und u.U. fehleranfällig ist, diese für menschliche LeserInnen ungewöhnliche Reihenfolge zu erstellen, kann man die Eigenschaft, ob der erste oder der letzte Treffer gültig sein soll, mit diesem einfachen logischen Schalter umstellen.

Ein Beispiel:

recode xx

0  : 10 = 1 /

10 : 15 = 2 /

15 : 9999 = 3

;

RECODELASTWINS = YES;

recode yy

0  : 10 = 1 /

10 : 15 = 2 /

15 : 9999 = 3

;

Eine 10 in xx würde eine 1 zum Resultat haben, eine 10 in yy würde auf eine 2 abgebildet. Diese Technik, Grenzwerte zweimal zu vergeben, ist von Vorteil, wenn es sich um echte 'Fließkomma'-Zahlen handelt, wie z.B. die verwendete Spritzmenge dividiert durch die Anbaufläche. Schreibt man stattdessen

RECODE zz

0  : 9.9999 = 1 /

10 : 14.9999 = 2 /

15 : 9999 = 3

;

besteht die Gefahr, dass Werte in den Lücken (z.B. 9.99995) vom RECODE ausgeschlossen bleiben. Solche Fehler sind zwar eher selten, aber, wie der Statistiker sagt: Seltene Ereignisse sind davon gekennzeichnet, dass sie auftreten.

An dieser Stelle eine kurze Anmerkung zur verwendeten Mathematik: GESStabs stellt auch bei RECODE in Rechnung, dass berechnete Werte in der 64-bit-Binärdarstellung eine unvermeidliche Rechenungenauigkeit haben. Es kann also z.B. bei einer Division von 1000/200 das Ergebnis 4.9999999 herauskommen. Ein RECODE, das jetzt den Grenzwert 5 enthält, wäre in Gefahr, falsch zu rekodieren:

RECODELASTWINS = YES;

RECODE xyz

0  : 5 = 1 /

5  : 15 = 2 /

15 : 9999 = 3

;

Man würde dies interpretieren als "0 bis unter 5", "5 bis unter 15" usw. Die 4.9999999 würde dann eine 1 ergeben, obwohl jeder Mensch mit rudimentären Rechenkenntnissen erkennt, dass das Ergebnis 5 ist und auf die 2 rekodiert werden müsste.

Lösung: GESStabs 'verschmiert' die Ränder der RECODE-Bereiche. 5:15 wird vom GESStabs-Compiler übersetzt als "(5-eps) : (15+eps)", eps ist eine positive Zahl sehr nahe Null. Dies stellt sicher, dass die Vorrangregel (gewinnt der erste oder der letzte Treffer) mehr Gewicht hat als eventuelle Rechen-Kunststücke des Fließkomma-Chips. Dies trifft auch zu bei 'einfachen' Rekodierungen: RECODE xyz 5=7; z.bB wird interpretiert als "RECODE xyz (5-eps) : (5+eps) = 7;".

CheckRecodes

Prüfung vorhandener RECODE-Anweisungen: Obergrenze >= Untergrenze, siehe Prüfungen.

Wenn dieser eingeschaltet ist, werden RECODE-Anweisungen darauf getestet, dass die Obergrenze >= der Untergrenze ist.

 

LabelRecode

Voreinstellung zu Nutzung von Recode als Labeloption, siehe oben.


Ranges

Erlaubt die Zusammenfassung von Ausprägungsbereichen (Ranges) zu Einzelcodes.

Syntax:

RANGES [<VarList>] <ValueList> ;

Es wird eine Reihe von Obergrenzen definiert.

Beispiel:

RANGES 1000 2000 3000 4000;

rekodiert für die zuletzt definierte Variable (= keine explizite Nennung) alle Werte < 1000 auf 1, < 2000 auf 2, < 3000 auf 3, < 4000 auf 4, >= 4000 auf 5.

Die Range-Werte können auch Dezimalpunkte enthalten, zum Beispiel hier für die Variable Points:

RANGES Points 0.1 0.2 0.3 0.4 0.5 0.6;

Wie bei RECODE können Variablen auch explizit benannt werden. VARGROUPs bzw. VARFAMILYs können ebenso benutzt werden wie bei RECODE.