Compute Variablen werden mit einem Namen
NAME
angelegt und enthalten
entweder direkt einen Zahlenwert oder ein
Berechnungsschema BERECHNUNG
mit
anderen Variablen, dessen Ergebnis jeweils im Moment
des Zugriffs ermittelt wird. Sie können wie folgt
angelegt, in vielerlei Hinsicht verwendet und auf
Wunsch auch optional mit dem Attribut
export
in den Datenexport
einbezogen werden.
compute VARNAME = BERECHNUNG; [export;]
Bei BERECHNUNG
handelt es sich im einfachsten
Fall um einen einfachen Zahlenwert, der mit dem ActionBefehl
set(VARNAME = VALUE);
beliebig verändert werden
kann. Im folgenden Beispiel soll nur beim ersten Betreten einer
Frage eine Initialisierungslogik ausgeführt werden:
compute initNotwendig = 1; TextQ intro; text = "Los geht's!"; continueActionBlock=" if(initNotwendig eq 1){ set(initNotwendig = 0); // do some init stuff }; ";
Compute Variablen können aber auch verwendet werden,
etwa um die Werte der vier numerischen Eingabefelder
einer NumQ mit dem Namen »punkte« zu addieren. Das
folgende Beispiel ist zwar überflüssig, da man die
Summe auch direkt unter dem Namen der NumQ
punkte
ansprechen kann,
verdeutlicht aber das Prinzip.
compute summe = punkte.1 + punkte.2 + punkte.3 + punkte.4;
Die Variable summe
enthält beim Zugriff zu
jedem Zeitpunkt das jeweils aktuelle Ergebnis der Berechnung.
Als Rechenoperatoren sind +, -, *, /, % (modulo) und Klammerausdrücke möglich. Korrekte Punkt vor Strich Rechnung wird eingehalten.
Eine Group
wird mit einem Namen NAME
, sowie einer leicht
modifizierten Labelliste angelegt und stellt einen Bezug zwischen LABELCODE
s, TEXT
en
und BEDINGUNG
en her. Die Bedingungen definieren zu jeder Zeit eines
Interviews, welche Labelcodes in der Group gerade vorhanden sind. Dieses Verhalten kann an diversen
Stellen eingesetzt werden, z.B. für die konditionale Übernahme von Texten in den Fragetext
oder für Restriktionen, die sich nicht einfach per Labelwert-Bezug zu anderen Fragen herstellen lassen.
Das optionale Attribut export
steuert, ob die Group beim Datenexport berücksichtigt werden
soll.
group NAME; labels= LABELCODE "TEXT" (BEDINGUNG) LABELCODE "TEXT" (BEDINGUNG) ... ; [export;]
Ein Beispiel: Es werden Geschlecht und Alter des
Befragten abgefragt, und je nachdem, was dieser
geantwortet hat, soll ein bestimmter Text (der sich
nicht direkt den Fragen nach Alter und Geschlecht
entnehmen lässt) in den Text der TextQ
meldung
eingebaut werden. Die mit
@insert
eingeblendete
Group
hilft bei der Realisierung.
SingleQ geschlecht; labels= 1 "Männlich" 2 "Weiblich" ; SingleQ alter; labels= 1 "18-39 Jahre" 2 "40-59 Jahre" ; group anrede; labels= 1 "Mein Herr, Sie sind 18-39 Jahre alt." (geschlecht eq 1 and alter eq 1) 2 "Mein Herr, Sie sind 40-59 Jahre alt." (geschlecht eq 1 and alter eq 2) 3 "Meine Dame, Sie sind 18-39 Jahre alt." (geschlecht eq 2 and alter eq 1) 4 "Meine Dame, Sie sind 40-59 Jahre alt." (geschlecht eq 2 and alter eq 2) ; TextQ meldung; text="@insert(anrede)";
Das Element der Group, dessen Bedingung erfüllt ist, wird als Text in den Fragetext übernommen.
Im Fall des Textersatz' werden alle zutreffenden Labels als Komma-separierte Liste ausgegeben. Das Trennzeichen und der letzte Trenner können frei festgelegt werden:
insert="SEP","CON";
Group myGroup; labels= 1 "1" (1 in abc) 2 "2" (2 in abc) 3 "3" (3 in abc) ; insert=" | ", " und "; // @insert(myGroup) sähe dann möglicherweise so aus: "1 | 2 und 3"
In diesen Beispiel ist der Sinn der Labelwerte noch nicht zu erkennen. Groups können auch als Vorlage für Restriktionen dienen. Beispielsweise sollen Automodelle nur dann abgefragt werden, wenn die Marke insgesamt bekannt ist (dies lässt sich zwar auch mit Labelfiltern lösen, aber es ist ja auch nur ein Beispiel):
MultiQ marken; text="Welche dieser Automarken kennen Sie?"; labels= 1 "Audi" 2 "BMW" 3 "Mercedes" ; group restr; labels= 1 "Audi" (marken eq 1) 2 "Audi" (marken eq 1) 3 "Audi" (marken eq 1) 4 "BMW" (marken eq 2) 5 "BMW" (marken eq 2) 6 "BMW" (marken eq 2) 7 "Mercedes" (marken eq 3) 8 "Mercedes" (marken eq 3) 9 "Mercedes" (marken eq 3) ; MultiQ modelle; text="Welche dieser Automodelle kennen Sie?"; labels= 1 "Audi A4" 2 "Audi A6" 3 "Audi A8" 4 "BMW 3er" 5 "BMW 5er" 6 "BMW 7er" 7 "Mercedes C-Klasse" 8 "Mercedes E-Klasse" 9 "Mercedes S-Klasse" ; restrict=restr;
Gruppen können neben den Bedingungen, die ihre Werte bestimmen, auch ein else-Label erhalten. Auf diese Weise ließe sich eine Voreinstellung für eine Gruppe festlegen, die durch bestimmte Bedingungen aufgehoben wird.
Group myGroup; labels= 1 "1" (1 in abc) 2 "2" (2 in abc) 3 "3" (3 in abc) 9 "9" else ;
Obwohl die group-Daten sich eindeutig von anderen Variablen herleiten lassen, werden sie im Datensatz abgelegt. Der Grund dafür ist, dass die Daten einer group sich auch aus Variablen definieren können, deren Zustand im Nachhinein nicht unbedingt immer nachvollziehbar ist, wie z.B. Zufallszahlen, Zeiten oder Quotenstände.
Die DictFileVar
implementiert einen
Dictionary-Mechanismus, der einem Schlüssel einen Wert
zuordnet. Beispielsweise ist eine Unterteilung
Deutschlands in Regionen (z.B. Nord, Süd, Ost und
West) denkbar. Die Befragten sollen ihre Postleitzahl
eingeben und werden darüber einer der vier
Regionen-Gruppen zugeordnet. Man hantiert dabei mit
der langen Liste aller deutschen Postleitzahlen, die
in vier Gruppen unterteilt werden soll. Dass ließe
sich mit einer Group
umsetzen, wäre
allerdings umständlich und verbrauchte
Software-Ressourcen. Hier ist die
DictFileVar
das Mittel der Wahl.
Die Syntax ist:
DictFileVar name=("Datei", Schlüsselvariable);
In der Datei stehen zeilenweise untereinander die Schlüssel und daneben die ihnen zugeordneten Werte. Die Schlüsselvariable enthält den Schlüsselwert (in unserem Beispiel also die Postleitzahl). Im folgenden Beispiel enthält die Datei »plz.txt« nur drei Zeilen mit zwei Postleitzahlen aus Hamburg und einer aus Berlin:
10247 3 20257 1 22359 1
Die Postleitzahl wird in einer NumQ namens »plz«
abgefragt, daher hat die Schlüsselvariable den Namen
»plz.1«. Die DictFileVar
sähe also
so aus:
DictFileVar region=("plz.txt", plz.1);
Wenn Befragte nun als Postleitzahl »10247« eingeben,
wird dieser Schlüssel-Wert in der Datei gesucht und
die DictFileVar
bekommt den ihr
zugeordneten Wert 3 (für »Ost«). Die
DictFileVar
kann nun wiederum für
Filter, Quoten usw. verwendet werden.
Sowohl beim Schlüssel als auch beim zugeordneten Wert kann es sich auch um Text handeln (anstelle von Zahlen). Der zugeordnete Wert kann auch direkt für Textersatz verwendet werden.
Zu beachten ist: Um ständige Dateizugriffe zu
vermeiden, wird der Inhalt der
DictFileVar
nur einmal ermittelt,
und zwar zum Zeitpunkt des ersten Zugriffs auf die
Datei. Voraussetzung für die Verwendung der
DictFileVar
ist daher, dass sich
die Zuordnungen nicht während der Interviewzeit
verändern. Zudem haben auch Änderungen an der
Schlüsselvariablen (beispielsweise durch ein
Zurückgehen und Ändern während des Interviews) keinen
Einfluss, nachdem der Wert einmal ermittelt wurde.
Mit einer DecisionVar
ist es
möglich, den Faktor, ob eine Bedingung erfüllt ist
oder nicht, in Berechnungen mit einzubeziehen.
Syntax:
DecisionVar name = (Bedingung);
Wenn die Bedigung erfüllt ist, hat die DecisionVar den Wert 1 ansonsten 0.
Mit IntRandom
lassen sich
ganzzahlige Zufallszahlen erzeugen. Die Syntax ist:
IntRandom name=von bis;
Für eine Zufallszahl zwischen 1 und 10 wäre das beispielsweise
IntRandomVar meineZufallszahl = 1 10;
Zu beachten ist, dass die Zufallszahl einmal bei Interviewstart ermittelt wird und dann während des gesamten Interviews konstant bleibt (genau wie alle anderen Zufalls-Elemente wie z.B. randomisierte Blöcke auch).
Wenn ein Block von Fragen durchlaufen wird, kann es
notwendig sein, zu ermitteln, an welcher Position in
diesem Block sich das Interview gerade befindet.
Beispielsweise können Fragen in einem randomisierten
Block stehen, und abhängig davon, ob eine Frage die
erste oder eine andere Position in diesem Block hat,
kann der Fragetext anders sein. Hierzu gibt es pro
Block je eine Variable, die diese Information liefert.
Die Variable wird automatisch generiert und trägt den
Namen count_
+Blockname. Wenn der
Block also »block1« hieße, würde die Blockzähl-Variable
count_block1
heißen. Beim
Durchgehen des Blocks enthält die Variable als Wert
die Position des Blocks, an dem sich das Interview
gerade befindet.
Beispiel:
Gegeben seien zwei Frage, q1 und q2. Diese erscheinen randomisiert im Block »block1«:
block block1=(q1 q2); random;
Je nachdem, ob eine Frage als erstes oder zweites kommt, soll der Fragetext anders sein. Beispielhaft für q1: Der Fragetext wird mittels Textersatz und einer group erzeugt.
group qtext_q1; labels= 1 "Fragetext q1 Erstvorlage" (count_block1 eq 1) 2 "Fragetext q2 Zweitvorlage" (count_block1 eq 2) ; SingleQ q1; text="@insert(qtext_q1)"; ...
TextElement
stellt eine einfache
Textvariable dar. Sie kann lediglich mit einem Namen
angelegt und in ActionBlöcken mittels
setText(TEXTVAR,
"’TEXT"’)
und appendText(TEXTVAR,
"’TEXT"’)
neu belegt oder um
einen weiteren Text verlängert werden.
TextElement meinTextElement; ActionBlock ab = { setText(meinTextElement, "Das ist ein"); appendText(meinTextElement, " Beispiel."); };
Mit der Anweisung saved
kann eine
Variable auch über Abbruch und Wiederaufnahme erhalten bleiben,
TextElement te = "ein Text" saved; // angelegt + gespeichert (Abbr/Wiederaufnahme)
Ein besonderer Variablentyp ist das
Array
. Ein Array speichert eine
Anzahl #WERTE
von Fließkommazahlen,
die sich per Index ansprechen lassen. Es kann von
außen betrachtet auch als einzelne, atomare Variable
angesprochen werden. Der Wert des Arrays entspricht
dann der Summe seiner einzelnen Elemente. Mit dem
optionalen Attribut export
wird das
Array beim Datenexport berücksichtigt.
Array VARNAME[#WERTE];
// Beispiel: Array zehnFelder[10]; [export;]
Ein neu angelegtes Array wird entsprechend der Einstellung
ArrayInitMode
initialisiert, siehe
„Skriptparameter“. Das Array zehnFelder
hat
demnach 10 Felder mit entsprechenden Werten, die mit eckigen
Klammern angesprochen werden können. Der Index beginnt bei 1.
zehnFelder[1] ... zehnFelder[10]
Arrays können z.B. in for
-Schleifen
mit Werten belegt werden, etwa um die Werte einer
Gruppe (hier auswahl) auf ein Array zu übertragen (nur
sinnvoll, wenn das Array mit _missing-Werten
initialisiert wurde):
compute max = 10; array arr[max]; for( zaehler=1 to max ) { if( zaehler in auswahl ) { set( arr[zaehler] = zaehler ); }; };
Alternativ kann das Array auch mit dem Action-Befehl
set
gefüllt werden, s. „Actionbefehle“.
Analog zu Array
gibt es auch einen
Variablentyp TextArray
, der
anstelle von mehreren Werten mehrere Texte enthält. Es
gibt zwei Möglichkeiten TextArrays zu initialisieren:
// Direkte Initialisierung mit Texten TextArray marken = {"Audi" "BMW" "Mercedes"}; // Indirekte Initialisierung mit den Labels einer Frage MultiQ q_marken; labels= 1 "Audi" 2 "BMW" 3 "Mercedes" ; TextArray marken = q_marken;
Wie auch bei normalen Arrays lassen sich die einzelnen Texte mit eckigen Klammern ansprechen und der Index beginnt bei 1.
Ein dritter Array-Typ neben Array
für Zahlen und TextArray
für Texte
steht mit VarArray
für Variablen zur
Verfügung. Einem VarArray
können wir
die Variablen direkt über ihre Namen übergeben und
dann auf die Werte über den Index zugreifen.
vararray NAME = (VAR1 VAR2 ...);
Die RestrictVar
kann als Schablone für den restrict
Befehl
verwendet werden, um Labellisten automatisch zu filtern. Das folgende Beispiel zeigt die Verwendung
mit SingleQs, um der Reihe nach die Plätze 1 bis 3 auf die Label zu verteilen.
RestrictVar NAME = TEMPLATE; singleq msq1; text="1. Platz"; labels= 1 "a" 2 "b" 3 "c" 4 "d" 5 "e" ; RestrictVar rsv = (not(msq1)); singleq msq2; text="2. Platz"; labels copy msq1; restrict=(not(msq1)); // restrict=rsv; // Alternative Schreibweise mit RestrictVar singleq msq3; text="3. Platz"; labels copy msq1; restrict=(not(msq1 or msq2));