Type: | Package |
Title: | Daten, Beispiele und Funktionen zu 'Large-Scale Assessment mit R' |
Version: | 1.0-3 |
Date: | 2022-05-17 |
Author: | Thomas Kiefer [aut, cre], Alexander Robitzsch [aut], Matthias Trendtel [aut], Robert Fellinger [aut] |
Maintainer: | Thomas Kiefer <thomas.kiefer@iqs.gv.at> |
Description: | Dieses R-Paket stellt Zusatzmaterial in Form von Daten, Funktionen und R-Hilfe-Seiten für den Herausgeberband Breit, S. und Schreiner, C. (Hrsg.). (2016). "Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung." Wien: facultas. (ISBN: 978-3-7089-1343-8, https://www.iqs.gv.at/themen/bildungsforschung/publikationen/veroeffentlichte-publikationen) zur Verfügung. |
Depends: | R (≥ 2.10) |
Imports: | lme4, Hmisc |
Suggests: | BIFIEsurvey, TAM, miceadds, sirt, mice, pls, WrightMap, irr, lavaan, difR, kerdiest, glmnet, mirt, car, mitml, matrixStats, combinat, xtable, tensor, gtools, plyr, prettyR, gridExtra, lattice |
License: | GPL (≥ 3) |
URL: | https://www.iqs.gv.at/themen/bildungsforschung/publikationen/veroeffentlichte-publikationen |
Language: | de |
Encoding: | UTF-8 |
NeedsCompilation: | no |
Packaged: | 2022-05-31 18:38:35 UTC; t.kiefer |
Repository: | CRAN |
Date/Publication: | 2022-06-01 07:50:02 UTC |
Daten, Beispiele und Funktionen zu 'Large-Scale Assessment mit R'
Description
Das Bundesinstitut für Bildungsforschung, Innovation und Entwicklung des
österreichischen Schulwesens (BIFIE) führt die Überprüfung der Bildungsstandards
(BIST-Ü) in Österreich durch. "Large-Scale Assessment mit R" ist ein Handbuch der
grundlegenden Methodik, die bei diesen Überprüfungen zum Einsatz kommt.
Angefangen bei der Testkonstruktion bis zu Aspekten der Rückmeldung werden die
dabei eingesetzten methodischen Verfahren dargestellt und diskutiert sowie deren
Anwendung in R anhand von Beispieldatensätzen, die in diesem R-Paket zur
Verfügung gestellt werden, illustriert.
Beispiele, die sich durch den Band ziehen, lehnen sich an die BIST-Ü in Englisch im Jahr 2013 an. Die Daten, die den Ausführungen zugrunde liegen, sind jedoch keine Echtdaten und erlauben daher auch keine Rekonstruktion der in den Ergebnisberichten publizierten Kennwerte. Es handelt sich (mindestens) um partiell-synthetische Daten, die reale Kovarianzstrukturen zwischen Kovariaten und den Leistungsdaten abbilden sowie eine Mehrebenenstruktur simulieren, die in den LSA-Erhebungen typischerweise auftreten. Die Datenmuster können weder als Einzelstücke noch als Ganzes auf tatsächliche Testpersonen, auf Klassen oder Schulen zurückgeführt werden. Ebenso führen Ergebnisse, die in den Ausführungen der einzelnen Kapitel erzielt werden, nicht zu den Datensätzen, die in späteren Kapiteln verwendet werden (z. B. entspricht die Stichprobe, die in Kapitel 2 gezogen wird, nicht jener, deren Testwerte in Kapitel 6 oder Kapitel 7 untersucht werden).
Author(s)
Thomas Kiefer [aut, cre], Alexander Robitzsch [aut], Matthias Trendtel [aut], Robert Fellinger [aut]
Maintainer: Thomas Kiefer <thomas.kiefer@iqs.gv.at>
References
Breit, S. & Schreiner, C. [HG.] (2016). Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Wien: facultas.
https://www.iqs.gv.at/themen/bildungsforschung/publikationen/veroeffentlichte-publikationen
See Also
Zu Kapitel 0
, Konzeption der Überprüfung der Bildungsstandards in Österreich.
Zu Kapitel 1
, Testkonstruktion.
Zu Kapitel 2
, Stichprobenziehung.
Zu Kapitel 3
, Standard-Setting.
Zu Kapitel 4
, Differenzielles Itemfunktionieren in Subgruppen.
Zu Kapitel 5
, Testdesign.
Zu Kapitel 6
, Skalierung und Linking.
Zu Kapitel 7
, Statistische Analysen produktiver Kompetenzen.
Zu Kapitel 8
, Fehlende Daten und Plausible Values.
Zu Kapitel 9
, Fairer Vergleich in der Rückmeldung.
Zu Kapitel 10
, Reporting und Analysen.
Zu Kapitel 11
, Aspekte der Validierung.
Examples
## Not run:
install.packages("LSAmitR", dependencies = TRUE)
library(LSAmitR)
package?LSAmitR
?"Kapitel 7"
data(datenKapitel07)
names(datenKapitel07)
dat <- datenKapitel07$prodRat
## End(Not run)
Kapitel 0: Konzeption der Ueberpruefung der Bildungsstandards in Oesterreich
Description
Das ist die Nutzerseite zum Kapitel 0, Konzeption der Überprüfung der Bildungsstandards in Österreich, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Hier werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert, dokumentiert und gegebenenfalls erweitert.
Details
Dieses Kapitel enthält keine Beispiele mit R.
Author(s)
Claudia Schreiner und Simone Breit
References
Schreiner, C. & Breit, S. (2016). Konzeption der Überprüfung der Bildungsstandards in Österreich. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 1–20). Wien: facultas.
See Also
Zu Kapitel 1
, Testkonstruktion.
Zur Übersicht
.
Kapitel 1: Testkonstruktion
Description
Das ist die Nutzerseite zum Kapitel 1, Testkonstruktion, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Author(s)
Ursula Itzlinger-Bruneforth, Jörg-Tobias Kuhn, und Thomas Kiefer
References
Itzlinger-Bruneforth, U., Kuhn, J.-T. & Kiefer, T. (2016). Testkonstruktion. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 21–50). Wien: facultas.
See Also
Zu datenKapitel01
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 0
, Konzeption.
Zu Kapitel 2
, Stichprobenziehung.
Zur Übersicht
.
Examples
## Not run:
library(TAM)
library(miceadds)
library(irr)
library(gtools)
library(car)
set.seed(1337)
data(datenKapitel01)
pilotScored <- datenKapitel01$pilotScored
pilotItems <- datenKapitel01$pilotItems
pilotRoh <- datenKapitel01$pilotRoh
pilotMM <- datenKapitel01$pilotMM
## -------------------------------------------------------------
## Abschnitt 1.5.5: Aspekte empirischer Güteüberprüfung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 1: Vorbereitung
#
# Rekodierter Datensatz pilotScored
dat <- pilotScored
items <- grep("E8R", colnames(dat), value = TRUE)
dat[items] <- recode(dat[items], "9=0;8=0")
# Itembank im Datensatz pilotItems
dat.ib <- pilotItems
items.dich <- dat.ib$item[dat.ib$maxScore == 1]
# Berechne erreichbare Punkte je TH
# aus Maximalscore je Item in Itembank
ind <- match(items, dat.ib$item)
testlets.ind <- ! items %in% items.dich
ind[testlets.ind] <- match(items[testlets.ind], dat.ib$testlet)
maxscores <- dat.ib$maxScore[ind]
max.form <- 1 * (!is.na(dat[, items])) %*% maxscores
# Erzielter Score ist der Summenscore dividiert durch
# Maximalscore
sumscore <- rowSums(dat[, items], na.rm = TRUE)
relscore <- sumscore/max.form
mean(relscore)
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 2: Omitted Response
#
library(TAM)
# Bestimme absolute und relative Häufigkeit der Kategorie 9 (OR)
ctt.omit <- tam.ctt2(pilotScored[, items])
ctt.omit <- ctt.omit[ctt.omit$Categ == 9, ]
# Übersicht der am häufigsten ausgelassenen Items
tail(ctt.omit[order(ctt.omit$RelFreq), -(1:4)])
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 3: Not Reached
#
not.reached <- rep(0, length(items))
names(not.reached) <- items
# Führe die Bestimmung in jedem Testheft durch
forms <- sort(unique(dat$form))
for(ff in forms){
# (1) Extrahiere Itempositionen
order.ff <- order(dat.ib[, ff], na.last = NA,
decreasing = TRUE)
items.ff <- dat.ib$item[order.ff]
testlets.ff <- dat.ib$testlet[order.ff]
# (2) Sortiere Items und Testlets nach den Positionen
testlets.ind <- ! items.ff %in% items.dich
items.ff[testlets.ind] <- testlets.ff[testlets.ind]
items.order.ff <- unique(items.ff)
# (3) Bringe Testhefte in Reihenfolge und
# zähle von hinten aufeinanderfolgende Missings
ind.ff <- pilotScored$form == ff
dat.order.ff <- pilotScored[ind.ff, items.order.ff]
dat.order.ff <- dat.order.ff == 9
dat.order.ff <- apply(dat.order.ff, 1, cumsum)
# (4) Vergleiche letzteres mit theoretisch möglichem
# vollständigen NR
vergleich <- cumsum(rep(1, length(items.order.ff)))
dat.order.ff[dat.order.ff != vergleich] <- 0
# (5) Erstes NR kann auch OR sein
erstes.NR <- apply(dat.order.ff, 2, which.max)
ind <- cbind(erstes.NR, 1:ncol(dat.order.ff))
dat.order.ff[ind] <- 0
# (6) Zähle, wie oft für ein Item NR gilt
not.reached.ff <- rowSums(dat.order.ff > 0)
not.reached[items.order.ff] <- not.reached.ff[items.order.ff] +
not.reached[items.order.ff]
}
tail(not.reached[order(not.reached)])
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 4: Itemschwierigkeit
#
# Statistik der relativen Lösungshäufigkeiten
p <- colMeans(dat[, items], na.rm = TRUE) / maxscores
summary(p)
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 5: Trennschärfe
#
discrim <- sapply(items, FUN = function(ii){
if(var(dat[, ii], na.rm = TRUE) == 0) 0 else
cor(dat[, ii], relscore, use = "pairwise.complete.obs")
})
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 6: Eindeutigkeit der Lösung
#
dat.roh <- pilotRoh
items <- grep("E8R", colnames(dat.roh), value = TRUE)
vars <- c("item", "Categ", "AbsFreq", "RelFreq", "rpb.WLE")
# Wähle nur geschlossene Items (d. h., nicht Open gap-fill)
items.ogf <- dat.ib$item[dat.ib$format == "Open gap-fill"]
items <- setdiff(items, items.ogf)
# Bestimme absolute und relative Häufigkeit der Antwortoptionen
# und jeweilige punktbiseriale Korrelationen mit dem Gesamtscore
ctt.roh <- tam.ctt2(dat.roh[, items], wlescore = relscore)
# Indikator der richtigen Antwort
match.item <- match(ctt.roh$item, dat.ib$item)
rohscore <- 1 * (ctt.roh$Categ == dat.ib$key[match.item])
# Klassifikation der Antwortoptionen
ist.antwort.option <- (!ctt.roh$Categ %in% c(8,9))
ist.distraktor <- rohscore == 0 & ist.antwort.option
ist.pos.korr <- ctt.roh$rpb.WLE > 0.05
ist.bearb <- ctt.roh$AbsFreq >= 10
# Ausgabe
ctt.roh[ist.distraktor & ist.pos.korr & ist.bearb, vars]
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 7: Plausible Distraktoren
#
# Ausgabe
head(ctt.roh[ist.distraktor & ctt.roh$RelFreq < 0.05, vars],4)
# -------------------------------------------------------------
# Abschnitt 1.5.5, Listing 8: Kodierbarkeit
#
library(irr)
dat.mm <- pilotMM
# Bestimme Modus der Berechnung: bei 3 Kodierern
# gibt es 3 paarweise Vergleiche
vars <- grep("Coder", colnames(dat.mm))
n.vergleiche <- choose(length(vars), 2)
ind.vergleiche <- upper.tri(diag(length(vars)))
# Berechne Statistik für jedes Item
coder <- NULL
for(ii in unique(dat.mm$item)){
dat.mm.ii <- dat.mm[dat.mm$item == ii, vars]
# Relative Häufigkeit der paarweisen Übereinstimmung
agreed <- apply(dat.mm.ii, 1, function(dd){
sum(outer(dd, dd, "==")[ind.vergleiche]) / n.vergleiche
})
# Fleiss Kappa
kappa <- kappam.fleiss(dat.mm.ii)$value
# Ausgabe
coderII <- data.frame("item" = ii,
"p_agreed" = mean(agreed),
"kappa" = round(kappa, 4))
coder <- rbind(coder, coderII)
}
## End(Not run)
Kapitel 2: Stichprobenziehung
Description
Das ist die Nutzerseite zum Kapitel 2, Stichprobenziehung, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Vorbereitungen
Zunächst werden die Datensätze schule
mit den 1.327 Schulen der
Population und schueler
mit den 51.644 Schüler/innen dieser Schulen
geladen.
Durch das Setzen eines festen Startwerts für den Zufallszahlengenerator
(set.seed(20150506)
) wird erreicht, dass wiederholte Programmdurchläufe
immer wieder zur selben Stichprobe führen.
Abschnitt 4.1: Stratifizierung - Schichtung einer Stichprobe
Die für die explizite Stratifizierung notwendige Information der Anzahl der
Schüler/innen pro Stratum wird durch Aggregierung (Summe) aus dem Schuldatensatz
in das Objekt strata
extrahiert. Die entsprechende Spalte wird aus
Gründen der Eindeutigkeit noch in NSchuelerStratum
umbenannt.
strata <- aggregate(schule[,"NSchueler", drop = FALSE],
by=schule[,"stratum", drop = FALSE], sum)
colnames(strata)[2] <- "NSchuelerStratum" #Ergänzung zum Buch
Abschnitt 4.2: Schulenziehung, Listing 1
Im Schuldatensatz wird eine Dummyvariable Klassenziehung
angelegt, die
indiziert, in welchen Schulen mehr als drei Klassen sind, aus denen in Folge
gezogen werden muss.
schule$Klassenziehung <- 0
schule[which(schule$NKlassen>3), "Klassenziehung"] <- 1
Abschnitt 4.2: Schulenziehung, Listing 2
Dann wird der unter Beachtung der Klassenziehung erwartete Beitrag der Schulen
(d. h. die Anzahl ihrer Schülerinnen bzw. Schüler) zur Stichprobe in der Spalte
NSchueler.erw
errechnet.
schule$NSchueler.erw <- schule$NSchueler
ind <- which(schule$Klassenziehung == 1)
schule[ind, "NSchueler.erw"] <-
schule[ind, "NSchueler"]/schule[ind, "NKlassen"]*3
Abschnitt 4.2: Schulenziehung, Listing 3
Berechnet man aus der erwarteten Anzahl von Lernenden pro Schule ihren relativen
Anteil (Spalte AnteilSchueler
) an der Gesamtschülerzahl im Stratum, so
kann per Mittelwertbildung die mittlere Anzahl (Spalte
NSchueler/Schule.erw
) von Lernenden einer Schule pro Stratum bestimmt
werden.
Die mittlere Anzahl der Schulen im Stratum wird zusätzlich mit den einfachen
Ziehungsgewichten der Schulen gewichtet, da große Schulen mit höherer
Wahrscheinlichkeit für die Stichprobe gezogen werden.
temp <- merge(schule[, c("SKZ","stratum","NSchueler")],
strata[, c("stratum","NSchuelerStratum")])
schule$AnteilSchueler <-
temp$NSchueler/temp$NSchuelerStratum
strata$"NSchueler/Schule.erw" <-
rowsum(apply(schule, 1, function(x)
x["NSchueler.erw"]*x["AnteilSchueler"]), schule$stratum)
Abschnitt 4.2: Schulenziehung, Listing 4
Schließlich erfolgt die Berechnung der Anzahl an Schulen
(Schulen.zu.ziehen
), die in jedem Stratum gezogen werden müssen, um einen
Stichprobenumfang von 2500 Schülerinnen bzw. Schülern in etwa einzuhalten.
strata$Schulen.zu.ziehen <-
round(2500/strata[,"NSchueler/Schule.erw"])
Abschnitt 4.2: Schulenziehung, Listing 5
Die Schulenliste wird vorab nach expliziten und impliziten Strata sortiert.
schule <- schule[order(schule$stratum, schule$NSchueler),]
Abschnitt 4.2: Schulenziehung, Listing 6
Das Sampling-Intervall pro Stratum wird bestimmt (Samp.Int
).
strata$Samp.Int <-
strata$NSchuelerStratum/strata$Schulen.zu.ziehen
Abschnitt 4.2: Schulenziehung, Listing 7
Ein zufälliger Startwert aus dem Bereich 1 bis Samp.Int
wird für jedes
Stratum bestimmt (Startwert
). Zur Festlegung eines festen Ausgangswertes
des Zufallszahlengenerators siehe oben unter "Vorbereitungen".
set.seed(20150506)
strata$Startwert <-
sapply(ceiling(strata$Samp.Int), sample, size = 1)
Abschnitt 4.2: Schulenziehung, Listing 8
Die Listenpositionen der Lernenden, deren Schulen gezogen werden, werden vom
Startwert ausgehend im Sampling-Intervall (pro Stratum) ermittelt.
Die Positionen werden im Objekt tickets
abgelegt.
tickets <- sapply(1:4, function(x)
trunc(0:(strata[strata$stratum==x,"Schulen.zu.ziehen"]-1)
* strata[strata$stratum==x, "Samp.Int"] +
strata$Startwert[x]))
Abschnitt 4.2: Schulenziehung, Listing 9
Um die Auswahl der Schulen (entsprechend den Tickets der Lernenden) direkt auf
der Schulliste durchführen zu können wird in NSchuelerKum
die kumulierte
Anzahl an Schülerinnen und Schülern nach Sortierung (siehe oben Abschnit 4.2,
Listing 5) berechnet.
schule$NSchuelerKum <-
unlist(sapply(1:4, function(x)
cumsum(schule[schule$stratum==x, "NSchueler"])))
Abschnitt 4.2: Schulenziehung, Listing 10
Durch die Dummy-Variable SInSamp
werden nun jene Schulen als zugehörig
zur Stichprobe markiert, von denen wenigstens eine Schülerin oder ein Schüler
in Listing 8 dieses Abschnitts ein Ticket erhalten hat.
schule$SInSamp <- 0
for(s in 1:4) {
NSchuelerKumStrat <-
schule[schule$stratum==s, "NSchuelerKum"]
inds <- sapply(tickets[[s]], function(x)
setdiff(which(NSchuelerKumStrat <= x),
which(NSchuelerKumStrat[-1] <= x)))
schule[schule$stratum==s, "SInSamp"][inds] <- 1 }
Abschnitt 4.2: Schulenziehung, Listing 11
Die Ziehungswahrscheinlichkeiten der Schulen (Z.Wsk.Schule
) werden für
die später folgende Gewichtung berechnet.
temp <- merge(schule[, c("stratum", "AnteilSchueler")],
strata[, c("stratum", "Schulen.zu.ziehen")])
schule$Z.Wsk.Schule <-
temp$AnteilSchueler*temp$Schulen.zu.ziehen
Abschnitt 4.3: Klassenziehung, Listing 1
Im Objekt schukla
werden zunächst notwendige Informationen für die
Klassenziehung zusammengetragen. Die Dummy-Variable KlInSamp
darin
indiziert schließlich gezogene Klassen (aus bereits gezogenen Schulen), wobei
aus Schulen mit drei oder weniger Klassen alle Klassen gezogen werden.
Daher wird der Aufruf von sample.int
mit min(3, length(temp))
parametrisiert.
schukla <- unique(merge(
schule[, c("SKZ","NKlassen", "Klassenziehung",
"Z.Wsk.Schule", "SInSamp")],
schueler[, c("SKZ", "idclass")], by="SKZ"))
schukla$KlInSamp <- 0
for(skz in unique(schukla[schukla$SInSamp==1,"SKZ"])) {
temp <- schukla[schukla$SKZ==skz, "idclass"]
schukla[schukla$idclass %in% temp[sample.int
(min(3, length(temp)))], "KlInSamp"] <- 1 }
Abschnitt 4.3: Klassenziehung, Listing 2
Die Ziehungswahrscheinlichkeit einer Klasse (Z.Wsk.Klasse
) kann
entsprechend der Dummy-Variable Klassenziehung
(siehe Abschnitt 4.2,
Listing 1) berechnet werden. Man beachte, dass entweder der erste oder der
zweite Term der Addition Null ergeben muss, sodass die Fallunterscheidung direkt
ausgedrückt werden kann.
schukla$Z.Wsk.Klasse <- ((1 - schukla$Klassenziehung) * 1 +
schukla$Klassenziehung * 3 / schukla$NKlassen)
Abschnitt 4.4: Gewichtung, Listing 1
Nachdem das Objekt schueler
um die Informationen zur Klassenziehung sowie
den Ziehungswahrscheinlichkeiten von Schule und Klasse ergänzt wird, kann die
Ziehungswahrscheinlichkeit einer Schülerin bzw. eines Schülers
(Z.Wsk.Schueler
) berechnet werden.
schueler <- merge(schueler, schukla[, c("idclass", "KlInSamp", "Z.Wsk.Schule",
"Z.Wsk.Klasse")],
by="idclass", all.x=T)
schueler$Z.Wsk.Schueler <-
schueler$Z.Wsk.Schule * schueler$Z.Wsk.Klasse
Abschnitt 4.4: Gewichtung, Listing 2
Nach Reduktion des Objekts schueler
auf die gezogenen Lernenden, werden
in temp
die nonresponse-Raten (Variable x
) bestimmt.
schueler <- schueler[schueler$KlInSamp==1,]
temp <- merge(schueler[, c("idclass",
"Z.Wsk.Schueler")],
aggregate(schueler$teilnahme,
by=list(schueler$idclass),
function(x) sum(x)/length(x)),
by.x="idclass", by.y="Group.1")
Abschnitt 4.4: Gewichtung, Listing 3
Mittels der Ziehungswahrscheinlichkeiten der Schülerinnen und Schüler sowie der
nonresponse-Raten (siehe vorangegangenes Listing) werden die (nicht normierten)
Schülergewichte (studwgt
) bestimmt.
schueler$studwgt <- 1/temp$x/temp$Z.Wsk.Schueler
Abschnitt 4.4: Gewichtung, Listing 4
Schließlich werden die Schülergewichte in Bezug auf die Anzahl an Schülerinnen
und Schülern im jeweiligen Stratum normiert (NormStudwgt
), sodass sie in
Summe dieser Anzahl entsprechen.
Normierung <- strata$NSchuelerStratum /
rowsum(schueler$studwgt * schueler$teilnahme,
group = schueler$Stratum)
schueler$NormStudwgt <-
schueler$studwgt * Normierung[schueler$Stratum]
Abschnitt 5.3: Anwendung per Jackknife-Repeated-Replication, Listing 1
Die im Folgenden genutzte Hilfsfunktion zones.within.stratum
erzeugt ab einem
Offset einen Vektor mit jeweils doppelt vorkommenden IDs zur Bildung der
Jackknife-Zonen.
Nachdem die Schulliste zunächst auf die gezogenen Schulen und nach expliziten
und impliziten Strata* sortiert wurde, werden die Strata in Pseudo-Strata mit
zwei (oder bei ungerader Anzahl drei) Schulen unterteilt.
Dies führt zur Variable jkzone
.
Basierend auf jkzone
wird für jeweils eine der Schulen im Pseudo-Stratum
der Indikator jkrep
auf Null gesetzt, um diese in der jeweiligen
Replikation von der Berechnung auszuschließen.
Ergänzend zum Buch wird hier eine Fallunterscheidung getroffen, ob in einem
Pseudo-Stratum zwei oder drei Schulen sind (s.o): Bei drei Schulen wird zufällig
ausgewählt, ob bei ein oder zwei Schulen jkrep=0
gesetzt wird.
* Die Sortierung nach dem impliziten Strata Schulgröße erfolgt hier absteigend, nachzulesen im Buch-Kapitel.
### Ergänzung zum Buch: Hilfsfunktion zones.within.stratum
zones.within.stratum <- function(offset,n.str) {
maxzone <- offset-1+floor(n.str/2)
zones <- sort(rep(offset:maxzone,2))
if (n.str %% 2 == 1) zones <- c(zones,maxzone)
return(zones) }
### Ende der Ergänzung
# Sortieren der Schulliste (explizite und implizite Strata)
schule <- schule[schule$SInSamp==1,]
schule <- schule[order(schule$stratum,-schule$NSchueler),]
# Unterteilung in Pseudostrata
cnt.strata <- length(unique(schule$stratum))
offset <- 1
jkzones.vect <- integer()
for (i in 1:cnt.strata) {
n.str <- table(schule$stratum)[i]
jkzones.vect <-
c(jkzones.vect,zones.within.stratum(offset,n.str))
offset <- max(jkzones.vect)+1 }
schule$jkzone <- jkzones.vect
# Zufällige Auswahl von Schulen mit Gewicht 0
schule$jkrep <- 1
cnt.zones <- max(schule$jkzone)
jkrep.rows.null <- integer()
for (i in 1:cnt.zones) {
rows.zone <- which(schule$jkzone==i)
### Ergänzung zum Buch: Fallunterscheidung je nach Anzahl Schulen in der Zone
if (length(rows.zone)==2) jkrep.rows.null <-
c(jkrep.rows.null,sample(rows.zone,size=1))
else {
num.null <- sample(1:2,size=1)
jkrep.rows.null <-
c(jkrep.rows.null,sample(rows.zone,size=num.null))
} }
schule[jkrep.rows.null,]$jkrep <- 0
Abschnitt 5.3: Anwendung per Jackknife-Repeated-Replication, Listing 2
Die Anwendung von Jackknife-Repeated-Replication zur Abschätzung der
Stichprobenvarianz wird im folgenden am Schülerdatensatz demonstriert, weswegen
jkzone
und jkrep
zunächst auf diese Aggregatsebene übertragen
werden.
In einer Schleife werden replicate weights mittels jkzone
und
jkrep
generiert.
Diese beziehen sich auf das normierte Schülergewicht NormStudwgt
.
Man beachte: Es gilt entweder in.zone==0
oder (in.zone-1)==0
,
sodass Formel 5 aus dem Buch-Kapitel direkt in einer Addition ausgedrückt werden
kann.
Es entstehen so viele replicate weights (w_fstr1
usw.) wie
Jackknife-Zonen existieren.
# Übertragung auf Schülerebene
schueler <-
merge(schueler,schule[,c("SKZ","jkzone","jkrep")],all.x=TRUE)
# Schleife zur Generierung von Replicate Weights
for (i in 1:cnt.zones) {
in.zone <- as.numeric(schueler$jkzone==i)
schueler[paste0("w_fstr",i)] <- # vgl. Formel 5
in.zone * schueler$jkrep * schueler$NormStudwgt * 2 +
(1-in.zone) * schueler$NormStudwgt }
Abschnitt 5.3: Anwendung per Jackknife-Repeated-Replication, Listing 3
Als einfaches Beispiel wird der Anteil Mädchen (perc.female
) in der
Population aus der Stichprobe heraus geschätzt. Die Schätzung selbst erfolgt als
Punktschätzung über das normierte Schülergewicht.
Zur Bestimmung der Stichprobenvarianz var.jrr
wird der Anteil wiederholt
mit allen replicate weights berechnet und die quadrierte Differenz zur
Punktschätzung einfach aufsummiert (Formel 6 aus dem Buch-Kapitel).
# Schätzung mittels Gesamtgewicht
n.female <- sum(schueler[schueler$female==1,]$NormStudwgt)
perc.female <- n.female / sum(schueler$NormStudwgt)
# wiederholte Berechnung und Varianz
var.jrr = 0
for (i in 1:cnt.zones) {
n.female.rep <-
sum(schueler[schueler$female==1,paste0("w_fstr",i)])
perc.female.rep <-
n.female.rep / sum(schueler[paste0("w_fstr",i)])
var.jrr <- # vgl. Formel 6
var.jrr + (perc.female.rep - perc.female) ^ 2.0 }
Author(s)
Ann Cathrice George, Konrad Oberwimmer, Ursula Itzlinger-Bruneforth
References
George, A. C., Oberwimmer, K. & Itzlinger-Bruneforth, U. (2016). Stichprobenziehung. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 51–81). Wien: facultas.
See Also
Zu datenKapitel02
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 1
, Testkonstruktion.
Zu Kapitel 3
, Standard-Setting.
Zur Übersicht
.
Examples
## Not run:
data(datenKapitel02)
schueler <- datenKapitel02$schueler
schule <- datenKapitel02$schule
set.seed(20150506)
## -------------------------------------------------------------
## Abschnitt 4.1: Stratifizierung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 4.1, Listing 1
# Information in Strata
strata <- aggregate(schule[,"NSchueler", drop = FALSE],
by=schule[,"stratum", drop = FALSE], sum)
colnames(strata)[2] <- "NSchuelerStratum"
## -------------------------------------------------------------
## Abschnitt 4.2: Schulenziehung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 1
# Dummyvariable Klassenziehung
schule$Klassenziehung <- 0
schule[which(schule$NKlassen>3), "Klassenziehung"] <- 1
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 2
# erwarteter Beitrag zur Stichprobe pro Schule
schule$NSchueler.erw <- schule$NSchueler
ind <- which(schule$Klassenziehung == 1)
schule[ind, "NSchueler.erw"] <-
schule[ind, "NSchueler"]/schule[ind, "NKlassen"]*3
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 3
# relativer Anteil Schüler pro Schule
temp <- merge(schule[, c("SKZ","stratum","NSchueler")],
strata[, c("stratum","NSchuelerStratum")])
schule$AnteilSchueler <-
temp$NSchueler/temp$NSchuelerStratum
# mittlere Anzahl von Schülern pro Schule
strata$"NSchueler/Schule.erw" <-
rowsum(apply(schule, 1, function(x)
x["NSchueler.erw"]*x["AnteilSchueler"]), schule$stratum)
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 4
# Bestimmung Anzahl zu ziehender Schulen
strata$Schulen.zu.ziehen <-
round(2500/strata[,"NSchueler/Schule.erw"])
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 5
# Schulenliste nach Stratum und Groesse ordnen
schule <-
schule[order(schule$stratum, schule$NSchueler),]
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 6
# Berechnung Sampling-Intervall
strata$Samp.Int <-
strata$NSchuelerStratum/strata$Schulen.zu.ziehen
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 7
# Startwerte bestimmen
strata$Startwert <-
sapply(ceiling(strata$Samp.Int), sample, size = 1)
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 8
# Schüler-Tickets
tickets <- sapply(1:4, function(x)
trunc(0:(strata[strata$stratum==x,"Schulen.zu.ziehen"]-1)
* strata[strata$stratum==x, "Samp.Int"] +
strata$Startwert[x]))
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 9
# kummulierte Schüleranzahl pro Stratum berechnen
schule$NSchuelerKum <-
unlist(sapply(1:4, function(x)
cumsum(schule[schule$stratum==x, "NSchueler"])))
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 10
# Schulen ziehen
schule$SInSamp <- 0
for(s in 1:4) {
NSchuelerKumStrat <-
schule[schule$stratum==s, "NSchuelerKum"]
inds <- sapply(tickets[[s]], function(x)
setdiff(which(NSchuelerKumStrat <= x),
which(NSchuelerKumStrat[-1] <= x)))
schule[schule$stratum==s, "SInSamp"][inds] <- 1 }
# -------------------------------------------------------------
# Abschnitt 4.2, Listing 11
# Berechnung Ziehungswahrscheinlichkeit Schule
temp <- merge(schule[, c("stratum", "AnteilSchueler")],
strata[, c("stratum", "Schulen.zu.ziehen")])
schule$Z.Wsk.Schule <-
temp$AnteilSchueler*temp$Schulen.zu.ziehen
## -------------------------------------------------------------
## Abschnitt 4.3: Klassenziehung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 4.3, Listing 1
### Klassenziehung (Alternative 2)
schukla <- unique(merge(
schule[, c("SKZ","NKlassen", "Klassenziehung",
"Z.Wsk.Schule", "SInSamp")],
schueler[, c("SKZ", "idclass")], by="SKZ"))
schukla$KlInSamp <- 0
for(skz in unique(schukla[schukla$SInSamp==1,"SKZ"])) {
temp <- schukla[schukla$SKZ==skz, "idclass"]
schukla[schukla$idclass%in%temp[sample.int(
min(3, length(temp)))], "KlInSamp"] <- 1 }
# -------------------------------------------------------------
# Abschnitt 4.3, Listing 2
# Ziehungswahrscheinlichkeit Klasse
schukla$Z.Wsk.Klasse <- ((1 - schukla$Klassenziehung) * 1 +
schukla$Klassenziehung * 3 / schukla$NKlassen)
## -------------------------------------------------------------
## Abschnitt 4.4: Gewichtung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 4.4, Listing 1
### Gewichte
schueler <- merge(schueler, schukla[, c("idclass", "KlInSamp", "Z.Wsk.Schule",
"Z.Wsk.Klasse")],
by="idclass", all.x=T)
# Ziehungswahrscheinlichkeiten Schueler
schueler$Z.Wsk.Schueler <-
schueler$Z.Wsk.Schule * schueler$Z.Wsk.Klasse
# -------------------------------------------------------------
# Abschnitt 4.4, Listing 2
schueler <- schueler[schueler$KlInSamp==1,]
# Nonresponse Adjustment
temp <- merge(schueler[, c("idclass", "Z.Wsk.Schueler")],
aggregate(schueler$teilnahme,
by=list(schueler$idclass),
function(x) sum(x)/length(x)),
by.x="idclass", by.y="Group.1")
# -------------------------------------------------------------
# Abschnitt 4.4, Listing 3
# Schülergewichte
schueler$studwgt <- 1/temp$x/temp$Z.Wsk.Schueler
# -------------------------------------------------------------
# Abschnitt 4.4, Listing 4
# Normierung
Normierung <- strata$NSchuelerStratum /
rowsum(schueler$studwgt * schueler$teilnahme,
group = schueler$Stratum)
schueler$NormStudwgt <-
schueler$studwgt * Normierung[schueler$Stratum]
## -------------------------------------------------------------
## Abschnitt 5.3: Jackknife-Repeated-Replication
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 5.3, Listing 1
### Ergänzung zum Buch: Hilfsfunktion zones.within.stratum
zones.within.stratum <- function(offset,n.str) {
maxzone <- offset-1+floor(n.str/2)
zones <- sort(rep(offset:maxzone,2))
if (n.str %% 2 == 1) zones <- c(zones,maxzone)
return(zones) }
### Ende der Ergänzung
# Sortieren der Schulliste (explizite und implizite Strata)
schule <- schule[schule$SInSamp==1,]
schule <- schule[order(schule$stratum,-schule$NSchueler),]
# Unterteilung in Pseudostrata
cnt.strata <- length(unique(schule$stratum))
offset <- 1
jkzones.vect <- integer()
for (i in 1:cnt.strata) {
n.str <- table(schule$stratum)[i]
jkzones.vect <-
c(jkzones.vect,zones.within.stratum(offset,n.str))
offset <- max(jkzones.vect)+1 }
schule$jkzone <- jkzones.vect
# Zufällige Auswahl von Schulen mit Gewicht 0
schule$jkrep <- 1
cnt.zones <- max(schule$jkzone)
jkrep.rows.null <- integer()
for (i in 1:cnt.zones) {
rows.zone <- which(schule$jkzone==i)
### Ergänzung zum Buch: Fallunterscheidung je nach Anzahl Schulen in der Zone
if (length(rows.zone)==2) jkrep.rows.null <-
c(jkrep.rows.null,sample(rows.zone,size=1))
else {
num.null <- sample(1:2,size=1)
jkrep.rows.null <-
c(jkrep.rows.null,sample(rows.zone,size=num.null))
} }
schule[jkrep.rows.null,]$jkrep <- 0
# -------------------------------------------------------------
# Abschnitt 5.3, Listing 2
# Übertragung auf Schülerebene
schueler <-
merge(schueler,schule[,c("SKZ","jkzone","jkrep")],all.x=TRUE)
# Schleife zur Generierung von Replicate Weights
for (i in 1:cnt.zones) {
in.zone <- as.numeric(schueler$jkzone==i)
schueler[paste0("w_fstr",i)] <- # vgl. Formel 5
in.zone * schueler$jkrep * schueler$NormStudwgt * 2 +
(1-in.zone) * schueler$NormStudwgt }
# -------------------------------------------------------------
# Abschnitt 5.3, Listing 3
# Schätzung mittels Gesamtgewicht
n.female <- sum(schueler[schueler$female==1,]$NormStudwgt)
perc.female <- n.female / sum(schueler$NormStudwgt)
# wiederholte Berechnung und Varianz
var.jrr = 0
for (i in 1:cnt.zones) {
n.female.rep <-
sum(schueler[schueler$female==1,paste0("w_fstr",i)])
perc.female.rep <-
n.female.rep / sum(schueler[paste0("w_fstr",i)])
var.jrr <- # vgl. Formel 6
var.jrr + (perc.female.rep - perc.female) ^ 2.0 }
## End(Not run)
Kapitel 3: Standard-Setting
Description
Das ist die Nutzerseite zum Kapitel 3, Standard-Setting, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Übersicht über die verwendeten Daten
Für dieses Kapitel werden drei Datensätze verwendet.
Der Datensatz ratings
ist das Ergebnis der IDM-Methode, darin enthalten
sind für alle Items die Einstufung jedes Raters auf eine der drei
Kompetenzstufen (1, 2, 3), sowie Item-Nummer und Schwierigkeit.
Der Datensatz bookmarks
ist das Ergebnis der Bookmark-Methode, darin
enthalten sind pro Rater und pro Cut-Score jeweils die gewählte Bookmark als
Seitenzahl im OIB (die ein bestimmtes Item repräsentiert).
In sdat
sind Personenparameter von 3500 Schülerinnen und Schülern
enthalten, diese dienen zur Schätzung von Impact Data.
Der Datensatz productive
ist für die Illustration der
Contrasting-Groups-Methode gedacht: Dieser enthält die Ratings aus der
Contrasting-Groups-Methode, pro Rater die Information, ob der entsprechende
Text auf die Stufe unter- oder oberhalb des Cut-Scores eingeteilt wurde, sowie
Nummer des Textes und Personenfähigkeit.
Abschnitt 3.2.2: Daten aus der IDM-Methode
Listing 1: Feedback
Hier wird der Datensatz ratings
verwendet. Er ist das Ergebnis der
IDM-Methode, darin enthalten sind für alle Items die Einstufung jedes Raters
auf eine der drei Kompetenzstufen (1, 2, 3). Zunächst werden die Rater und die
Items aus dem Datensatz ausgewählt, dann wird pro Item die prozentuelle
Verteilung der Ratings auf die drei Stufen berechnet.
raterID <- grep("R", colnames(ratings), value = TRUE)
nraters <- length(raterID)
nitems <- nrow(ratings)
itemID <- ratings[, 1]
itemdiff <- ratings[, 2]
stufen <- c(1, 2, 3) # Anzahl der Kompetenzstufen
item.freq <- data.frame()
# Berechne Prozentuelle Zuteilungen auf Stufen pro Item
tabelle.ii <- data.frame()
for(ii in 1:nitems){
tabelle.ii <- round(table(factor(as.numeric(ratings[ii,
raterID]), levels = stufen)) / nraters * 100, digits = 2)
item.freq <- rbind(item.freq, tabelle.ii) }
colnames(item.freq) <- paste0("Level_", stufen)
item.freq <- data.frame(ratings[, 1:2], item.freq)
head(item.freq, 3)
# Anmerkung: Item 3 zu 100% auf Stufe 1, Item 2 aufgeteilt
# auf Stufe 1 und 2
Listing 1a: Ergänzung zum Buch
Hier wird eine Grafik erzeugt, in der das Rating-Verhalten sichtbar wird: Pro Item wird angezeigt, wieviele Prozent der Raters es auf eine der drei Stufen eingeteilt haben. Zunächst werden drei verschiedene Farben definiert, anschließend werden drei Barplots erstellt, die zusammen auf einer Seite dargestellt werden. Die Grafik wird zur Orientierung bei Diskussionen verwendet, da so schnell ersichtlich ist, bei welchen Items sich das Experten-Panel einig oder uneinig war. Für die Grafik gibt es die Möglichkeit, diese in Schwarz-Weiss zu halten oder in Farbe zu gestalten.
# Farben für die Grafik definieren - falls eine bunte Grafik gewünscht ist,
# kann barcol <- c(c1, c2, c3) definiert werden
c1 <- rgb(239/255, 214/255, 67/255)
c2 <- rgb(207/255, 151/255, 49/255)
c3 <- rgb(207/255, 109/255, 49/255)
# Aufbereitung Tabelle für Grafik
freq.dat <- t(as.matrix(item.freq[1:nitems,(3:(2+length(stufen)))]))
barcol <- c("black", "gray", "white")
#Grafik wird erzeugt
par(mfcol=c(3,1), oma=c(0,0,3,0)) # Angeben der Plot-Anzahl
perplot <- round(nitems/3)
a <- perplot + 1
b <- perplot*2
c <- b + 1
d <- perplot*3
barplot(freq.dat[,1 : perplot], col = barcol, beside = T,
names.arg = seq(1 , perplot), xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe", horiz = F, ylim = range(1:100))
barplot(freq.dat[, a:b], col = barcol, beside = T, names.arg = seq(a, b),
xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe",
horiz = F, ylim = range(1:100))
barplot(freq.dat[, c:d], col = barcol, beside = T, names.arg = seq(c, d),
xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe",
horiz = F, ylim = range(1:100))
title("Feedback für das Experten-Panel aus der IDM-Methode", outer = T)
Listing 2: Cut-Score Berechnung
Hier wird der Cut-Score aus den Daten der IDM-Methode mithilfe logistischer Regression für den ersten Rater im Experten-Panel berechnet. Dafür wird der zweite Cut-Score herangezogen. Zunächst müssen die entsprechenden Ratings für die logistische Regression umkodiert werden (2 = 0, 3 = 1). Anschließend wird die logistische Regression berechnet, als unabhängige Variable dient die Einstufung durch den jeweiligen Experten (0, 1), als abhängige Variable die Itemschwierigkeit. Anhand der erhaltenen Koeffizienten kann der Cut-Score berechnet werden.
library(car)
# Rekodieren
rate.i <- ratings[which(ratings$R01 %in% c(2, 3)),
c("MB_Norm_rp23", "R01")]
rate.i$R01 <- recode(rate.i$R01, "2=0; 3=1")
coef(cut.i <- glm(rate.i$R01 ~ rate.i$MB_Norm_rp23 ,
family = binomial(link="logit")))
# Berechnung des Cut-Scores laut Formel
cut.R01 <- (-cut.i$coefficients[1])/ cut.i$coefficients[2]
Listing 3: Rater-Analysen
Als ersten Schritt in den Rater-Analysen wird das mittlere Cohen's Kappa eines Raters mit allen anderen Raters berechnet. Dafür werden zunächst die Ratings ausgewählt und dann für jeden Rater die Übereinstimmung mit jedem anderen Rater paarweise berechnet. Anschließend werden diese Werte gemittelt und auch die Standard-Abweichung berechnet.
library(irr)
# Auswahl der Ratings
rater.dat <- ratings[ ,grep("R", colnames(ratings))]
# Kappa von jeder Person mit allen anderen Personen wird berechnet
kappa.mat <- matrix(NA, nraters, nraters)
for(ii in 1:nraters){
rater.eins <- rater.dat[, ii]
for(kk in 1:nraters){
rater.zwei <- rater.dat[ ,kk]
dfr.ii <- cbind(rater.eins, rater.zwei)
kappa.ik <- kappa2(dfr.ii)
kappa.mat[ii, kk] <- kappa.ik$value
}}
diag(kappa.mat) <- NA
# Berechne Mittleres Kappa für jede Person
MW_Kappa <- round(colMeans(kappa.mat, na.rm=T), digits=2)
SD_Kappa <- round(apply(kappa.mat, 2, sd, na.rm=T), digits=2)
(Kappa.Stat <- data.frame("Person"= raterID, MW_Kappa, SD_Kappa))
Listing 4: Berechnung Fleiss' Kappa
Fleiss' Kappa gibt die Übereinstimmung innerhalb des gesamten Experten-Panels an. Wird das Standard-Setting über mehrere Runden durchgeführt, kann Fleiss' Kappa auch für jede Runde berechnet werden.
kappam.fleiss(rater.dat)
Listing 5: Modalwerte
Auch die Korrelation zwischen dem Modalwert jedes Items (d.h., ob es am häufigsten auf Stufe 1, 2 oder 3 eingeteilt wurde) und der inviduellen Zuordnung durch einen Rater kann zu Rater-Analysen herangezogen werden. Zunächst wird der Modal-Wert eines jeden Items berechnet. Hat ein Item zwei gleich häufige Werte, gibt es eine Warnmeldung und es wird für dieses Item NA anstatt eines Wertes vergeben (für diese Analyse sind aber nur Items von Interesse, die einen eindeutigen Modalwert haben). Danach wird pro Rater die Korrelation zwischen dem Modalwert eines Items und der entsprechenden Einteilung durch den Rater berechnet, und dann in aufsteigender Höhe ausgegeben.
library(prettyR)
# Berechne Modalwert
mode <- as.numeric(apply(rater.dat, 1, Mode))
# Korrelation für die Ratings jeder Person im Panel mit den
# Modalwerten der Items
corr <- data.frame()
for(z in raterID){
rater.ii <- rater.dat[, (grep(z, colnames(rater.dat)))]
cor.ii <- round(cor(mode, rater.ii, use = "pairwise.complete.obs",
method = "spearman"), digits = 2)
corr <- rbind(corr, cor.ii)
}
corr[, 2] <- raterID
colnames(corr) <- c("Korrelation", "Rater")
# Aufsteigende Reihenfolge
(corr <- corr[order(corr[, 1]),])
Listing 5a: Ergänzung zum Buch
Die Korrelation zwischen Modalwerten und individueller Zuordnung kann auch zur besseren Übersicht graphisch gezeigt werden. Dabei werden die Korrelationen der Raters aufsteigend dargestellt.
# Grafik
plot(corr$Korrelation, xlab = NA, ylab = "Korrelation",
ylim = c(0.5, 1), xaxt = "n", main = "Korrelation zwischen
Modalwert und individueller Zuordnung der Items pro Rater/in")
text(seq(1:nraters), corr$Korrelation - 0.02, labels = corr[, 2],
offset = 1, cex = 1)
title(xlab = "Raters nach aufsteigender Korrelation gereiht")
Listing 6: ICC
Hier wird der ICC als Ausdruck der Übereinstimmung (d.h., Items werden auf dieselbe Stufe eingeteilt) und der Konsistenz (d.h., Items werden in dieselbe Reihenfolge gebracht) zwischen Raters berechnet. Falls es mehrere Runden gibt, kann der ICC auch wiederholt berechnet und verglichen werden.
library(irr)
(iccdat.agree <- icc(rater.dat, model = "twoway", type = "agreement",
unit = "single", r0 = 0, conf.level=0.95))
(iccdat.cons <- icc(rater.dat, model = "twoway", type = "consistency",
unit = "single", r0 = 0, conf.level=0.95))
Abschnitt 3.2.3: Daten aus der Bookmark-Methode
Listing 1: Feedback
Auch in der Bookmark-Methode wird dem Experten-Panel Feedback angeboten, um die Diskussion zu fördern. Hier wird pro Cut-Score Median, Mittelwert und Standard-Abweichung der Bookmarks (Seitenzahl im OIB) im Experten-Panel berechnet.
head(bookmarks)
statbookm <- data.frame("Stats"=c("Md","Mean","SD"),
"Cut1"=0, "Cut2"=0)
statbookm[1,2] <- round(median(bookmarks$Cut1), digits=2)
statbookm[1,3] <- round(median(bookmarks$Cut2), digits=2)
statbookm[2,2] <- round(mean(bookmarks$Cut1), digits=2)
statbookm[2,3] <- round(mean(bookmarks$Cut2), digits=2)
statbookm[3,2] <- round(sd(bookmarks$Cut1), digits=2)
statbookm[3,3] <- round(sd(bookmarks$Cut2), digits=2)
(statbookm)
table(bookmarks$Cut1)
table(bookmarks$Cut2)
Listing 2: Cut-Score Berechnung
Jede Bookmark repräsentiert ein Item, das eine bestimmte Itemschwierigkeit hat. Die Cut-Scores lassen sich berechnen, in dem man die unterliegenden Itemschwierigkeiten der Bookmarks mittelt.
bm.cut <- NULL
bm.cut$cut1 <- mean(ratings$MB_Norm_rp23[bookmarks$Cut1])
bm.cut$cut2 <- mean(ratings$MB_Norm_rp23[bookmarks$Cut2])
bm.cut$cut1sd <- sd(ratings$MB_Norm_rp23[bookmarks$Cut1])
bm.cut$cut2sd <- sd(ratings$MB_Norm_rp23[bookmarks$Cut2])
Listing 3: Standardfehler des Cut-Scores
Der Standardfehler wird berechnet, um eine mögliche Streuung des Cut-Scores zu berichten.
se.cut1 <- bm.cut$cut1sd/sqrt(nraters)
se.cut2 <- bm.cut$cut2sd/sqrt(nraters)
Listing 4: Impact Data
Mithilfe von Impact Data wird auf Basis von pilotierten Daten geschätzt, welche Auswirkungen die Cut-Scores auf die Schülerpopulation hätten (d.h., wie sich die Schülerinnen und Schüler auf die Stufen verteilen würden). Für diese Schätzung werden die Personenparameter herangezogen. Anschließend wird die Verteilung der Personenparameter entsprechend der Cut-Scores unterteilt. Die Prozentangaben der Schülerinnen und Schüler, die eine bestimmte Stufe erreichen, dienen dem Experten-Panel als Diskussionsgrundlage.
Pers.Para <- sdat[, "TPV1"]
cuts <- c(bm.cut$cut1, bm.cut$cut2)
# Definiere Bereiche: Minimaler Personenparameter bis Cut-Score 1,
# Cut-Score 1 bis Cut-Score 2, Cut-Score 2 bis maximaler
# Personenparameter
Cuts.Vec <- c(min(Pers.Para)-1, cuts, max(Pers.Para)+1)
# Teile Personenparameter in entsprechende Bereiche auf
Kum.Cuts <- cut(Pers.Para, breaks = Cuts.Vec)
# Verteilung auf die einzelnen Bereiche
Freq.Pers.Para <- xtabs(~ Kum.Cuts)
nstud <- nrow(sdat)
# Prozent-Berechnung
prozent <- round(as.numeric(Freq.Pers.Para / nstud * 100),
digits = 2)
(Impact.Data <- data.frame("Stufe" = c("A1", "A2", "B1"),
"Prozent" = prozent))
Abschnitt 3.3.3: Daten aus der Contrasting-Groups-Methode
Listing 1: Cut-Scores
Hier wird der Cut-Score für den produktiven Bereich Schreiben berechnet, die Basis ist dabei die Personenfähigkeeit. Dabei wird pro Rater vorgegangen. Für jeden Rater werden dabei zwei Gruppen gebildet - Texte, die auf die untere Stufe eingeteilt wurden und Texte, die auf die obere Stufe eingeteilt wurden. Von beiden Gruppen wird jeweils der Mittelwert der Personenfähigkeit berechnet und anschließend der Mittelwert zwischen diesen beiden Gruppen. Wurde das für alle Raters durchgeführt, können die individuell gesetzten Cut-Scores wiederum gemittelt werden und die Standard-Abweichung sowie der Standardfehler berechnet werden.
raterID <- grep("R", colnames(productive), value = TRUE)
nraters <- length(raterID)
nscripts <- nrow(productive)
# Berechne Cut-Score für jeden Rater
cutscore <- data.frame("rater"=raterID, "cut1.ges"=NA)
for(ii in 1:length(raterID)){
rater <- raterID[ii]
rates.ii <- productive[ ,grep(rater, colnames(productive))]
mean0.ii <- mean(productive$Performance[rates.ii == 0], na.rm = T)
mean1.ii <- mean(productive$Performance[rates.ii == 1], na.rm = T)
mean.ii <- mean(c(mean1.ii, mean0.ii), na.rm = T)
cutscore[ii, "cut1.ges"] <- mean.ii }
# Finaler Cut-Score
cut1 <- mean(cutscore$cut1.ges)
sd.cut1 <- sd(cutscore$cut1.ges)
se.cut1 <- sd.cut1/sqrt(nraters)
Appendix: Abbildungen im Buch
Hier ist der R-Code für die im Buch abgedruckten Grafiken zu finden.
Abbildung 3.1
In einem nächsten Schritt wird anhand des mittleren Kappa und der dazugehörigen Standard-Abweichung eine Grafik erstellt, um die Übereinstimmung eines Raters mit allen anderen Ratern dazustellen. Dafür wird zunächst ein Boxplot des mittleren Kappa pro Rater erzeugt. In einem zweiten Schritt werden die mittleren Kappas mit der dazugehörigen Standard-Abweichung abgetragen. Linien markieren 1.5 Standard-Abweichungen vom Mittelwert. Raters, die über oder unter dieser Grenze liegen, werden gekennzeichnet.
# GRAFIK
# 1. Grafik
par(fig=c(0, 1, 0, 0.35), oma=c(0,0,3,0), cex = 0.85)
boxplot(Kappa.Stat$MW_Kappa, horizontal = T, ylim=c(0.42,0.66),
axes = F, xlab = "MW Kappa")
# 2. Grafik wird hinzugefügt
par(fig=c(0, 1, 0.2, 1), new=TRUE)
sd.factor <- 1.5
mmw <- mean(Kappa.Stat$MW_Kappa)
sdmw <- sd(Kappa.Stat$MW_Kappa)
#Grenzwerte für MW und SD werden festgelegt
mwind <- c(mmw-(sd.factor*sdmw), mmw+(sd.factor*sdmw))
plot(Kappa.Stat$MW_Kappa, Kappa.Stat$SD_Kappa, xlab = "",
ylab = "SD Kappa", type = "n", xlim = c(0.42, 0.66),
ylim = c(0, 0.2))
abline(v = mwind, col="grey", lty = 2)
# Rater mit 1.5 SD Abweichung vom MW werden grau markiert
abw.rater <- which(Kappa.Stat$MW_Kappa < mwind[1] |
Kappa.Stat$MW_Kappa > mwind[2])
points(Kappa.Stat$MW_Kappa[-abw.rater],
Kappa.Stat$SD_Kappa[-abw.rater],
pch = 19)
points(Kappa.Stat$MW_Kappa[abw.rater],
Kappa.Stat$SD_Kappa[abw.rater],
pch = 25, bg = "grey")
text(Kappa.Stat$MW_Kappa[abw.rater],
Kappa.Stat$SD_Kappa[abw.rater],
Kappa.Stat$Person[abw.rater],
pos = 3)
title("Rater-Analysen: MW und SD Kappa aus der IDM-Methode",
outer = TRUE)
Abbildung 3.2
Um das Feedback über die Setzung der Bookmarks an das Experten-Panel einfacher zu gestalten, wird eine Grafik erstellt. Darin sieht man pro Cut-Score, wo die Raters ihre Bookmarks (d.h. Seitenzahl im OIB) gesetzt haben, sowie Info über den Mittelwert dieser Bookmarks. Diese Grafik soll die Diskussion fördern.
nitems <- 60
library(lattice)
library(gridExtra)
#Erster Plot mit Mittelwert
plot.Cut1 <- dotplot(bookmarks$Rater ~ bookmarks$Cut1, col = "black",
panel = function(...){
panel.dotplot(...)
panel.abline(v = mean(bookmarks$Cut1), lty = 5)
},
xlab = "Bookmarks für Cut-Score 1 (Seite im OIB)",
ylab = "Raters", cex = 1.3)
#Zweiter Plot mit Mittelwert
plot.Cut2 <- dotplot(bookmarks$Rater ~ bookmarks$Cut2, col = "black",
panel = function(...){
panel.dotplot(...)
panel.abline(v = mean(bookmarks$Cut2), lty = 5)
},
xlab = "Bookmarks für Cut-Score 2 (Seite im OIB)",
ylab = "Raters", cex = 1.3)
#Plots nebeneinander anordnen
grid.arrange(plot.Cut1, plot.Cut2, nrow = 1, top = "Bookmarks pro Rater/in")
Author(s)
Claudia Luger-Bazinger, Roman Freunberger, Ursula Itzlinger-Bruneforth
References
Luger-Bazinger, C., Freunberger, R. & Itzlinger-Bruneforth, U. (2016). Standard-Setting. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 83–110). Wien: facultas.
See Also
Zu datenKapitel03
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 2
, Stichprobenziehung.
Zu Kapitel 4
, Differenzielles Itemfunktionieren in Subgruppen.
Zur Übersicht
.
Examples
## Not run:
library(car)
library(irr)
library(prettyR)
library(lattice)
library(gridExtra)
data(datenKapitel03)
ratings <- datenKapitel03$ratings
bookmarks <- datenKapitel03$bookmarks
sdat <- datenKapitel03$sdat
productive <- datenKapitel03$productive
## -------------------------------------------------------------
## Abschnitt 3.2.2: Daten aus der IDM-Methode
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 1: Feedback
#
raterID <- grep("R", colnames(ratings), value = TRUE)
nraters <- length(raterID)
nitems <- nrow(ratings)
itemID <- ratings[, 1]
itemdiff <- ratings[, 2]
stufen <- c(1, 2, 3) # Anzahl der Kompetenzstufen
item.freq <- data.frame()
# Berechne Prozentuelle Zuteilungen auf Stufen pro Item
tabelle.ii <- data.frame()
for(ii in 1:nitems){
tabelle.ii <- round(table(factor(as.numeric(ratings[ii,
raterID]), levels = stufen)) / nraters * 100, digits = 2)
item.freq <- rbind(item.freq, tabelle.ii) }
colnames(item.freq) <- paste0("Level_", stufen)
item.freq <- data.frame(ratings[, 1:2], item.freq)
head(item.freq, 3)
# Anmerkung: Item 3 zu 100% auf Stufe 1, Item 2 aufgeteilt
# auf Stufe 1 und 2
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 1a: Ergänzung zum Buch
# GRAFIK-Erzeugung
#
# Farben für die Grafik definieren
c1 <- rgb(239/255, 214/255, 67/255)
c2 <- rgb(207/255, 151/255, 49/255)
c3 <- rgb(207/255, 109/255, 49/255)
# Aufbereitung Tabelle für Grafik
freq.dat <- t(as.matrix(item.freq[1:nitems,(3:(2+length(stufen)))]))
barcol <- c("black", "gray", "white")
#Grafik wird erzeugt
par(mfcol=c(3,1), oma=c(0,0,3,0)) # Angeben der Plot-Anzahl
perplot <- round(nitems/3)
a <- perplot + 1
b <- perplot*2
c <- b + 1
d <- perplot*3
barplot(freq.dat[,1 : perplot], col = barcol, beside = T,
names.arg = seq(1 , perplot), xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe", horiz = F, ylim = range(1:100))
barplot(freq.dat[, a:b], col = barcol, beside = T, names.arg = seq(a, b),
xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe",
horiz = F, ylim = range(1:100))
barplot(freq.dat[, c:d], col = barcol, beside = T, names.arg = seq(c, d),
xlab = "Itemnummer (Seitenzahl im OIB)",
ylab = "% Zuteilung auf Stufe",
horiz = F, ylim = range(1:100))
title("Feedback für das Experten-Panel aus der IDM-Methode", outer = T)
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 2: Cut-Score Berechnung
#
library(car)
# Rekodieren
rate.i <- ratings[which(ratings$R01 %in% c(2, 3)),
c("Norm_rp23", "R01")]
rate.i$R01 <- recode(rate.i$R01, "2=0; 3=1")
coef(cut.i <- glm(rate.i$R01 ~ rate.i$Norm_rp23 ,
family = binomial(link="logit")))
# Berechnung des Cut-Scores laut Formel
cut.R01 <- (-cut.i$coefficients[1])/ cut.i$coefficients[2]
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 3: Rater-Analysen
#
library(irr)
# Auswahl der Ratings
rater.dat <- ratings[ ,grep("R", colnames(ratings))]
# Berechne Kappa von jeder Person mit allen anderen Personen
kappa.mat <- matrix(NA, nraters, nraters)
for(ii in 1:nraters){
rater.eins <- rater.dat[, ii]
for(kk in 1:nraters){
rater.zwei <- rater.dat[ ,kk]
dfr.ii <- cbind(rater.eins, rater.zwei)
kappa.ik <- kappa2(dfr.ii)
kappa.mat[ii, kk] <- kappa.ik$value }}
diag(kappa.mat) <- NA
# Berechne Mittleres Kappa für jede Person
MW_Kappa <- round(colMeans(kappa.mat, na.rm=T), digits=2)
SD_Kappa <- round(apply(kappa.mat, 2, sd, na.rm=T), digits=2)
(Kappa.Stat <- data.frame("Person"= raterID, MW_Kappa,
SD_Kappa))
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 4: Berechnung Fleiss' Kappa
#
kappam.fleiss(rater.dat)
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 5: Modalwerte
#
library(prettyR)
# Berechne Modalwert
mode <- as.numeric(apply(rater.dat, 1, Mode))
# Korrelation für die Ratings jeder Person im Panel mit den
# Modalwerten der Items
corr <- data.frame()
for(z in raterID){
rater.ii <- rater.dat[, (grep(z, colnames(rater.dat)))]
cor.ii <- round(cor(mode, rater.ii, method = "spearman",
use = "pairwise.complete.obs"), digits = 2)
corr <- rbind(corr, cor.ii)
}
corr[, 2] <- raterID
colnames(corr) <- c("Korrelation", "Rater")
# Aufsteigende Reihenfolge
(corr <- corr[order(corr[, 1]),])
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 5: Ergänzung zum Buch
# GRAFIK-Erzeugung und ICC
#
# Grafik
plot(corr$Korrelation, xlab = NA, ylab = "Korrelation",
ylim = c(0.5, 1), xaxt = "n", main = "Korrelation zwischen
Modalwert und individueller Zuordnung der Items pro Rater/in")
text(seq(1:nraters), corr$Korrelation - 0.02, labels = corr[, 2],
offset = 1, cex = 1)
title(xlab = "Raters nach aufsteigender Korrelation gereiht")
# -------------------------------------------------------------
# Abschnitt 3.2.2, Listing 6: ICC
#
library(irr)
(iccdat.agree <- icc(rater.dat, model = "twoway",
type = "agreement", unit = "single", r0 = 0, conf.level=0.95))
(iccdat.cons <- icc(rater.dat, model = "twoway",
type = "consistency", unit = "single", r0 = 0, conf.level=0.95))
## -------------------------------------------------------------
## Abschnitt 3.2.3: Daten aus der Bookmark-Methode
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 3.2.3, Listing 1: Feedback
#
head(bookmarks)
statbookm <- data.frame("Stats"=c("Md","Mean","SD"),
"Cut1"=0, "Cut2"=0)
statbookm[1,2] <- round(median(bookmarks$Cut1), digits=2)
statbookm[1,3] <- round(median(bookmarks$Cut2), digits=2)
statbookm[2,2] <- round(mean(bookmarks$Cut1), digits=2)
statbookm[2,3] <- round(mean(bookmarks$Cut2), digits=2)
statbookm[3,2] <- round(sd(bookmarks$Cut1), digits=2)
statbookm[3,3] <- round(sd(bookmarks$Cut2), digits=2)
(statbookm)
table(bookmarks$Cut1)
table(bookmarks$Cut2)
# -------------------------------------------------------------
# Abschnitt 3.2.3, Listing 2: Cut-Score Berechnung
#
bm.cut <- NULL
bm.cut$cut1 <- mean(ratings$Norm_rp23[bookmarks$Cut1])
bm.cut$cut2 <- mean(ratings$Norm_rp23[bookmarks$Cut2])
bm.cut$cut1sd <- sd(ratings$Norm_rp23[bookmarks$Cut1])
bm.cut$cut2sd <- sd(ratings$Norm_rp23[bookmarks$Cut2])
# -------------------------------------------------------------
# Abschnitt 3.2.3, Listing 3: Standardfehler des Cut-Scores
#
se.cut1 <- bm.cut$cut1sd/sqrt(nraters)
se.cut2 <- bm.cut$cut2sd/sqrt(nraters)
# -------------------------------------------------------------
# Abschnitt 3.2.3, Listing 4: Impact Data
#
Pers.Para <- sdat[, "TPV1"]
cuts <- c(bm.cut$cut1, bm.cut$cut2)
# Definiere Bereiche: Minimaler Personenparameter bis Cut-Score 1,
# Cut-Score 1 bis Cut-Score 2, Cut-Score 2 bis maximaler
# Personenparameter
Cuts.Vec <- c(min(Pers.Para)-1, cuts, max(Pers.Para)+1)
# Teile Personenparameter in entsprechende Bereiche auf
Kum.Cuts <- cut(Pers.Para, breaks = Cuts.Vec)
# Verteilung auf die einzelnen Bereiche
Freq.Pers.Para <- xtabs(~ Kum.Cuts)
nstud <- nrow(sdat)
# Prozent-Berechnung
prozent <- round(as.numeric(Freq.Pers.Para / nstud * 100),
digits = 2)
(Impact.Data <- data.frame("Stufe" = c("A1", "A2", "B1"),
"Prozent" = prozent))
## -------------------------------------------------------------
## Abschnitt 3.3.2: Daten aus der Contrasting-Groups-Methode
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 3.3.2, Listing 1: Cut-Scores
#
raterID <- grep("R", colnames(productive), value = TRUE)
nraters <- length(raterID)
nscripts <- nrow(productive)
# Berechne Cut-Score für jeden Rater
cutscore <- data.frame("rater"=raterID, "cut1.ges"=NA)
for(ii in 1:length(raterID)){
rater <- raterID[ii]
rates.ii <- productive[ ,grep(rater, colnames(productive))]
mean0.ii <- mean(productive$Performance[rates.ii == 0],
na.rm = TRUE)
mean1.ii <- mean(productive$Performance[rates.ii == 1],
na.rm = TRUE)
mean.ii <- mean(c(mean1.ii, mean0.ii), na.rm = TRUE)
cutscore[ii, "cut1.ges"] <- mean.ii }
# Finaler Cut-Score
cut1 <- mean(cutscore$cut1.ges)
sd.cut1 <- sd(cutscore$cut1.ges)
se.cut1 <- sd.cut1/sqrt(nraters)
## -------------------------------------------------------------
## Appendix: Abbildungen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abbildung 3.1
#
# 1. Grafik
par(fig=c(0, 1, 0, 0.35), oma=c(0,0,3,0), cex = 0.85)
boxplot(Kappa.Stat$MW_Kappa, horizontal = T, ylim=c(0.42,0.66),
axes = F, xlab = "MW Kappa")
# 2. Grafik wird hinzugefügt
par(fig=c(0, 1, 0.2, 1), new=TRUE)
sd.factor <- 1.5
mmw <- mean(Kappa.Stat$MW_Kappa)
sdmw <- sd(Kappa.Stat$MW_Kappa)
#Grenzwerte für MW und SD werden festgelegt
mwind <- c(mmw-(sd.factor*sdmw), mmw+(sd.factor*sdmw))
plot(Kappa.Stat$MW_Kappa, Kappa.Stat$SD_Kappa, xlab = "",
ylab = "SD Kappa", type = "n", xlim = c(0.42, 0.66),
ylim = c(0, 0.2))
abline(v = mwind, col="grey", lty = 2)
# Rater mit 1.5 SD Abweichung vom MW werden grau markiert
abw.rater <- which(Kappa.Stat$MW_Kappa < mwind[1] |
Kappa.Stat$MW_Kappa > mwind[2])
points(Kappa.Stat$MW_Kappa[-abw.rater],
Kappa.Stat$SD_Kappa[-abw.rater],
pch = 19)
points(Kappa.Stat$MW_Kappa[abw.rater],
Kappa.Stat$SD_Kappa[abw.rater],
pch = 25, bg = "grey")
text(Kappa.Stat$MW_Kappa[abw.rater],
Kappa.Stat$SD_Kappa[abw.rater],
Kappa.Stat$Person[abw.rater],
pos = 3)
title("Rater-Analysen: MW und SD Kappa aus der IDM-Methode",
outer = TRUE)
# -------------------------------------------------------------
# Abbildung 3.2
#
nitems <- 60
library(lattice)
library(gridExtra)
#Erster Plot mit Mittelwert
plot.Cut1 <- dotplot(bookmarks$Rater ~ bookmarks$Cut1, col = "black",
panel = function(...){
panel.dotplot(...)
panel.abline(v = mean(bookmarks$Cut1), lty = 5)
},
xlab = "Bookmarks für Cut-Score 1 (Seite im OIB)",
ylab = "Raters", cex = 1.3)
#Zweiter Plot mit Mittelwert
plot.Cut2 <- dotplot(bookmarks$Rater ~ bookmarks$Cut2, col = "black",
panel = function(...){
panel.dotplot(...)
panel.abline(v = mean(bookmarks$Cut2), lty = 5)
},
xlab = "Bookmarks für Cut-Score 2 (Seite im OIB)",
ylab = "Raters", cex = 1.3)
#Plots nebeneinander anordnen
grid.arrange(plot.Cut1, plot.Cut2, nrow = 1, top = "Bookmarks pro Rater/in")
## End(Not run)
Kapitel 4: Differenzielles Itemfunktionieren in Subgruppen
Description
Das ist die Nutzerseite zum Kapitel 4, Differenzielles Itemfunktionieren in Subgruppen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Author(s)
Matthias Trendtel, Franziska Schwabe, Robert Fellinger
References
Trendtel, M., Schwabe, F. & Fellinger, R. (2016). Differenzielles Itemfunktionieren in Subgruppen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 111–147). Wien: facultas.
See Also
Zu datenKapitel04
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 3
, Standard-Setting.
Zu Kapitel 5
, Testdesign.
Zur Übersicht
.
Examples
## Not run:
library(difR)
library(mirt)
library(sirt)
library(TAM)
set.seed(12345)
data(datenKapitel04)
dat <- datenKapitel04$dat
dat.th1 <- datenKapitel04$dat.th1
ibank <- datenKapitel04$ibank
## -------------------------------------------------------------
## Abschnitt 4.4.1 DIF-Analysen für vollständige Daten
## -------------------------------------------------------------
items.th1 <- grep("E8R", colnames(dat.th1), value=T)
resp <- dat.th1[, items.th1]
AHS <- dat.th1$AHS
# -------------------------------------------------------------
# Abschnitt 4.4.1, Listing 1: Mantel-Haenszel
#
difMH(Data = resp, group = AHS, correct = F, focal.name = 0)
# -------------------------------------------------------------
# Abschnitt 4.4.1, Listing 2: Standardisierte p-Wert Differenzen
#
difStd(Data = resp, group = AHS, focal.name = 0)
# -------------------------------------------------------------
# Abschnitt 4.4.1, Listing 3: SIBTEST
#
SIBTEST(dat = resp, group = AHS, focal_name = 0,
focal_set = grep("E8RS03131", items.th1))
SIBTEST(dat = resp, group = AHS, focal_name=0,
focal_set = grep("E8RS15621", items.th1))
# -------------------------------------------------------------
# Abschnitt 4.4.1, Listing 4: Methode nach Lord
#
difLord(Data = resp, group = AHS, focal.name = 0,
model = "1PL")
# -------------------------------------------------------------
# Abschnitt 4.4.1, Listing 5: Zusammenschau
#
dichoDif(Data = resp, group = AHS, correct = F, focal.name = 0,
method = c("MH", "Std", "Lord"), model = "1PL")
## -------------------------------------------------------------
## Abschnitt 4.4.2 DIF-Analysen für unvollständige Daten
## -------------------------------------------------------------
items <- grep("E8R", colnames(dat), value = T)
resp <- dat[ ,items]
AHS <- dat$AHS
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 1: Matching-Variable setzen
#
score <- rowSums(resp, na.rm=T)
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 2: Durchführung Logistische Regression
#
difLR <- dif.logistic.regression(resp, group = AHS, score = score)
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 3: Durchführung Logistische Regression
# mit angepasster Referenzgruppe
#
difLR <- dif.logistic.regression(resp, AHS==0, score)
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 4: Ausgabe erster Teil
#
cbind(item = difLR$item, round(difLR[, 4:13], 3))
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 5: Ausgabe zweiter Teil
#
cbind(difLR[, c(3,14:16)], sign = difLR[, 17], ETS = difLR[, 18])
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 6: DIF-Größen
#
table(difLR[, 17], difLR[, 18])
difLR[c(10, 18), c(3, 14, 17:18)]
# -------------------------------------------------------------
# Abschnitt 4.4.2, Listing 7: Ausgabe dritter Teil
#
cbind(difLR[, c(3, 21:23)], sign=difLR[, 24])
## -------------------------------------------------------------
## Abschnitt 4.4.3 Hypothesenprüfung mit GLMM
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 1: Itemauswahl
#
HO.items <- ibank[ibank$format == "ho", "task"]
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 2: Facettenidentifikation
#
facets <- data.frame(AHS = dat$AHS)
form <- formula( ~ item * AHS)
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 3: Initiierung des Designs
#
design <- designMatrices.mfr(resp = dat[, items],
formulaA = form, facets = facets)
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 4: Übergabe der Designmatrix und des
# erweiterten Responsepatterns
#
A <- design$A$A.3d[, , 1:(length(items) + 2)]
dimnames(A)[[3]] <- c(items, "AHS", "HO:AHS")
resp <- design$gresp$gresp.noStep
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 5: Ausgabe der ersten Zeilen des
# Responsepatterns
#
head(resp)
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 6: Identifikation Itemformat X Gruppe
#
HO.AHS0 <- paste0(HO.items, "-AHS0")
HO.AHS1 <- paste0(HO.items, "-AHS1")
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 7: Spezifizierung des Designs
#
A[, , "HO:AHS"] <- 0
A[HO.AHS0, 2, "HO:AHS"] <- -1; A[HO.AHS1, 2, "HO:AHS"] <- 1
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 8: Ausgabe der Designmatrix für
# Itemkategorie 'richtig beantwortet'
#
A[,2,c("AHS", "HO:AHS")]
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 9: Schätzen des Modells
#
mod <- tam.mml(resp = resp, A=A)
# -------------------------------------------------------------
# Abschnitt 4.4.3, Listing 10: Ausgabe der Parameterschätzer
#
summary(mod)
## End(Not run)
Kapitel 5: Testdesign
Description
Das ist die Nutzerseite zum Kapitel 5, Testdesign, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Author(s)
Thomas Kiefer, Jörg-Tobias Kuhn, Robert Fellinger
References
Kiefer, T., Kuhn, J.-T. & Fellinger, R. (2016). Testdesign. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 149–184). Wien: facultas.
See Also
Zurück zu Kapitel 4
, Differenzielles Itemfunktionieren in
Subgruppen.
Zu Kapitel 6
, Skalierung und Linking.
Zur Übersicht
.
Examples
## Not run:
library(tensor)
set.seed(1337)
data(datenKapitel05)
dat.ib <- datenKapitel05$tdItembank
dat.bib <- datenKapitel05$tdBib2d
dat.bibPaare <- datenKapitel05$tdBibPaare
## -------------------------------------------------------------
## Abschnitt 5.3.2: ATA Methode für das Blockdesign
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 1: Initialisierung
#
library(tensor)
nTh <- 30
nPos <- 6
nBl <- 30
inc <- array(0, dim = c(nTh, nPos, nBl))
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 2: Startdesign
#
for(tt in 1:nTh){
inc[tt, , sample(1:nBl, nPos)] <- diag(1, nPos)
}
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 3: Zielfunktion
#
des <- inc
desAllePos <- tensor(des, rep(1, nPos), 2, 1)
blockPaarInd <- upper.tri(diag(nrow = nBl))
blockPaar <- crossprod(desAllePos)[blockPaarInd]
err.bb <- blockPaar
err.bb[blockPaar >= 2] <- blockPaar[blockPaar >= 2] - 2
err.bb[blockPaar <= 1] <- 1 - blockPaar[blockPaar <= 1]
objective <- sum(err.bb) / length(err.bb)
objWgt <- 2^0
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 4: Studienzuweisung
#
blMatching <- seq(6, nBl, 6)
nbStatus <- list(
(desAllePos[1:6, -(1:12)] > 0) / (6 * 18), # 1
(desAllePos[25:30, -(19:30)] > 0) / (6 * 18), # 2
(rowSums(desAllePos[, blMatching]) != 1) / nTh # 3
)
nbStatus <- unlist(lapply(nbStatus, sum))
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 5: Erweiterung Positionsbalancierung
#
# 4
nbPos <- sum((colSums(des) != 1) / (nPos * nBl))
# 5
nbPos.pLSA <- list(
(colSums(des[1:6, 1:2, 1:12], dims = 2) != 1) / 12,
(colSums(des[1:6, 3:4, 1:12], dims = 2) != 1) / 12,
(colSums(des[1:6, 5:6, 1:12], dims = 2) != 1) / 12
)
nbPos.pLSA <- sum(unlist(lapply(nbPos.pLSA, sum)) / 3)
# 6
nbPos.link <- list(
(colSums(des[25:30, 1:2, 19:30], dims = 2) != 1) / 12,
(colSums(des[25:30, 3:4, 19:30], dims = 2) != 1) / 12,
(colSums(des[25:30, 5:6, 19:30], dims = 2) != 1) / 12
)
nbPos.link <- sum(unlist(lapply(nbPos.link, sum)) / 3)
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 6: Zusammenfügen
#
nb <- c(nbStatus, nbPos, nbPos.pLSA, nbPos.link)
nbWgt <- c(
rep(2^5, length(nbStatus)),
rep(2^6, length(nbPos)),
rep(2^4, length(nbPos.pLSA)),
rep(2^3, length(nbPos.link))
)
nbWgt.norm <- nbWgt / (sum(nbWgt) + objWgt)
objWgt.norm <- objWgt / (sum(nbWgt) + objWgt)
oDes <- objWgt.norm %*% objective + nbWgt.norm %*% nb
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 6a: Ergänzung zum Buch
#
#
fit <- function(des){
desAllePos <- tensor(des, rep(1, nPos), 2, 1)
#
blockPaarInd <- upper.tri(diag(nrow = nBl))
blockPaar <- crossprod(desAllePos)[blockPaarInd]
err.bb <- blockPaar
err.bb[blockPaar >= 2] <- blockPaar[blockPaar >= 2] - 2
err.bb[blockPaar <= 1] <- 1 - blockPaar[blockPaar <= 1]
objective <- sum(err.bb) / length(err.bb)
objWgt <- 2^0
#
nbStatus <- list(
(desAllePos[1:6, -(1:12)] > 0) / (6 * 18), # 1
(desAllePos[25:30, -(19:30)] > 0) / (6 * 18), # 2
(rowSums(desAllePos[, blMatching]) != 1) / nTh # 3
)
nbStatus <- unlist(lapply(nbStatus, sum))
# 4
nbPos <- sum((colSums(des) != 1) / (nPos * nBl))
# 5
nbPos.pLSA <- list(
(colSums(des[1:6, 1:2, 1:12], dims = 2) != 1) / 12,
(colSums(des[1:6, 3:4, 1:12], dims = 2) != 1) / 12,
(colSums(des[1:6, 5:6, 1:12], dims = 2) != 1) / 12
)
nbPos.pLSA <- sum(unlist(lapply(nbPos.pLSA, sum)) / 3)
# 6
nbPos.link <- list(
(colSums(des[25:30, 1:2, 19:30], dims = 2) != 1) / 12,
(colSums(des[25:30, 3:4, 19:30], dims = 2) != 1) / 12,
(colSums(des[25:30, 5:6, 19:30], dims = 2) != 1) / 12
)
nbPos.link <- sum(unlist(lapply(nbPos.link, sum)) / 3)
#
nb <- c(nbStatus, nbPos, nbPos.pLSA, nbPos.link)
nbWgt <- c(
rep(2^5, length(nbStatus)),
rep(2^6, length(nbPos)),
rep(2^4, length(nbPos.pLSA)),
rep(2^3, length(nbPos.link))
)
nbWgt.norm <- nbWgt / (sum(nbWgt) + objWgt)
objWgt.norm <- objWgt / (sum(nbWgt) + objWgt)
oDes <- objWgt.norm %*% objective + nbWgt.norm %*% nb
return(oDes)
}
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 7: Initialisierung des Algorithmus
#
# t <- 1; t.min <- 1e-5; c <- 0.7; L <- 10000; l <- 1
t <- 1; tMin <- 1e-5; c <- 0.9; L <- 100000; l <- 1
fitInc <- fit(inc)
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 8: Störung
#
thisTh <- (l - 1) %% nTh + 1
child <- inc
bloeckeTh <- which(colSums(child[thisTh, , ]) == 1)
raus <- sample(bloeckeTh, 1)
rein <- sample(setdiff(1:nBl, bloeckeTh), 1)
child[thisTh, , rein] <- child[thisTh, , raus]
child[thisTh, , raus] <- 0
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 9: Survival
#
fitChild <- fit(child)
behalte <- fitChild < fitInc
if(!behalte){
pt <- exp(-(fitChild - fitInc) / t)
behalte <- runif(1) <= pt
}
if(behalte){
inc <- child
fitInc <- fitChild
}
# -------------------------------------------------------------
# Abschnitt 5.3.2, Listing 9a: Ergänzung zum Buch
#
# Achtung: Algorithmus benötigt einige Zeit.
# Je nach Wahl der Lauf-Parameter in Abschnitt 5.3.2, Listing 7, kann der
# folgende Prozess bis zu ein paar Stunden dauern.
start <- Sys.time()
best <- list(inc, fitInc)
while(t > tMin){
while(l < L){
thisTh <- (l - 1) %% nTh + 1
child <- inc
# Perturbation
bloeckeTh <- which(colSums(child[thisTh, , ]) == 1)
raus <- sample(bloeckeTh, 1)
rein <- sample(setdiff(1:nBl, bloeckeTh), 1)
child[thisTh, , rein] <- child[thisTh, , raus]
child[thisTh, , raus] <- 0
# Fit und Survival
fitChild <- fit(child)
behalte <- fitChild < fitInc
if(!behalte){
pt <- exp(-(fitChild - fitInc) / t)
behalte <- runif(1) <= pt
}
if(behalte){
inc <- child
fitInc <- fitChild
}
# Kontroll-Ausgaben
if(fitInc < best[[2]]){
best <- list(inc, fitInc)
}
if (l %% 500 == 0) {
cat("\r")
cat(paste("l=", l),
paste("t=", as.integer(log(t) / log(c) + 1)),
paste("fit=", round(fitInc, 4)),
paste("pt=", round(pt, 5)),
sep="; ")
cat(" ")
flush.console()
}
l <- l + 1
}
l <- 1
t <- t * c
}
end <- Sys.time()
tdBib2d <- apply(inc, 1, function(bb){
this <- which(colSums(bb) > 0)
this[order((1:nrow(bb) %*% bb)[this])]
})
## -------------------------------------------------------------
## Abschnitt 5.3.3: ATA Methode für die Item-zu-Block-Zuordnung
## -------------------------------------------------------------
set.seed(1338)
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 1: Initialisierung
#
nTh <- nrow(dat.bib)
nPos <- ncol(dat.bib)
nBl <- length(unique(unlist(dat.bib)))
blMatching <- seq(6, nBl, 6)
nI <- nrow(dat.ib)
itemsMatching <- which(dat.ib$format == "Matching")
itemsSonst <- which(dat.ib$format != "Matching")
# -------------------------------------------------------------
# Abschnitt 3.3, Listing 2: Startdesign
#
inc <- array(0, dim = c(nI, nBl))
for(bb in blMatching){
inc[sample(itemsMatching, 2), bb] <- 1
}
for(bb in setdiff(1:nBl, blMatching)){
inc[sample(itemsSonst, 7), bb] <- 1
}
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 3: Testheftebene
#
des <- inc
desTh <- des[, dat.bib[, 1]] + des[, dat.bib[, 2]] +
des[, dat.bib[, 3]] + des[, dat.bib[, 4]] +
des[, dat.bib[, 5]] + des[, dat.bib[, 6]]
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 4: IIF
#
theta <- c(380, 580)
InfoItem <- dat.ib[,grep("IIF", colnames(dat.ib))]
TIF <- (t(InfoItem) %*% desTh) / 37
objective <- - sum(TIF) / prod(dim(TIF))
objWgt <- 2^0
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 5: KEY
#
nbKey <- list(
(colSums(desTh > 1) > 0) / nTh, # 7
((rowSums(desTh[, 1:6]) > 0) + # 8
(rowSums(desTh[, 25:30]) > 0) > 1) / nI
)
nbKey <- unlist(lapply(nbKey, sum))
nbWgt <- 2^c(7, 6)
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 6: Kategorial
#
# 9
zFocus.block <- c(0, 1, 1, 1, 1, 2, 0)
gFocus.block <- rowsum(des[, -blMatching], dat.ib$focus) -
zFocus.block
# 10
zFocus.form <- c(2, 6, 6, 6, 6, 13, 1)
gFocus.form <- rowsum(desTh, dat.ib$focus) - zFocus.form
# 11
gTopic.form <- rowsum(desTh, dat.ib$topic) - 4
nbKonstrukt <- list(
colSums(gFocus.block < 0) / prod(dim(gFocus.block)),
colSums(gFocus.form > 0) / prod(dim(gFocus.form)),
colSums(gTopic.form > 0) / 30
)
nbKonstrukt <- unlist(lapply(nbKonstrukt, sum))
nbWgt <- c(nbWgt, 2^c(4, 4, 3))
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 7: Stetig
#
length.form <- ((dat.ib$audiolength + 13) %*% desTh) / 60
nbStetig <- list(
(length.form > 32) / length(length.form),
(length.form < 28) / length(length.form)
)
nbStetig <- unlist(lapply(nbStetig, sum))
nbWgt <- c(nbWgt, 2^c(3, 2))
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 8: Perturbation
#
thisBl <- 1
child <- inc
items.raus <- which(child[, thisBl] == 1)
raus <- sample(items.raus, 1)
bibPaar.bl <- dat.bibPaare[thisBl, ] != 0
items.bibPaare <- rowSums(child[, bibPaar.bl]) > 0
rein <- which(!items.bibPaare)
if(thisBl %in% blMatching){
rein <- sample(intersect(rein, itemsMatching), 1)
}else{
rein <- sample(intersect(rein, itemsSonst), 1)
}
child[c(raus, rein), thisBl] <- c(0, 1)
# -------------------------------------------------------------
# Abschnitt 5.3.3, Listing 8a: Ergänzung zum Buch
# Vollständige Umsetzung
#
# Achtung: Algorithmus benötigt einige Zeit.
# Je nach Wahl der Lauf-Parameter im nachfolgenden Abschnitt, kann der
# Prozess bis zu einigen Stunden dauern.
fit <- function(des, dat.ib, dat.bib){
desTh <- des[, dat.bib[, 1]] + des[, dat.bib[, 2]] +
des[, dat.bib[, 3]] + des[, dat.bib[, 4]] +
des[, dat.bib[, 5]] + des[, dat.bib[, 6]]
#
TIF <- (t(InfoItem) %*% desTh) / 37
objective <- - sum(TIF) / prod(dim(TIF))
objWgt <- 2^0
#
nbKey <- list(
(colSums(desTh > 1) > 0) / nTh, # 7
((rowSums(desTh[, 1:6]) > 0) + # 8
(rowSums(desTh[, 25:30]) > 0) > 1) / nI
)
nbKey <- unlist(lapply(nbKey, sum))
nbWgt <- 2^c(7, 6)
# 9
zFocus.block <- c(0, 1, 1, 1, 1, 2, 0)
gFocus.block <- rowsum(des[, -blMatching], dat.ib$focus) -
zFocus.block
# 10
zFocus.form <- c(2, 6, 6, 6, 6, 13, 1)
gFocus.form <- rowsum(desTh, dat.ib$focus) - zFocus.form
# 11
gTopic.form <- rowsum(desTh, dat.ib$topic) - 4
nbKonstrukt <- list(
colSums(gFocus.block < 0) / prod(dim(gFocus.block)),
colSums(gFocus.form > 0) / prod(dim(gFocus.form)),
colSums(gTopic.form > 0) / 30
)
nbKonstrukt <- unlist(lapply(nbKonstrukt, sum))
nbWgt <- c(nbWgt, 2^c(4, 4, 3))
#
length.form <- ((dat.ib$audiolength + 13) %*% desTh) / 60
nbStetig <- list(
(length.form > 32) / length(length.form),
(length.form < 28) / length(length.form)
)
nbStetig <- unlist(lapply(nbStetig, sum))
nbWgt <- c(nbWgt, 2^c(3, 2))
#
nb <- c(nbKey, nbKonstrukt, nbStetig)
nbWgt.norm <- nbWgt / (sum(nbWgt) + objWgt)
objWgt.norm <- objWgt / (sum(nbWgt) + objWgt)
oDes <- objWgt.norm %*% objective + nbWgt.norm %*% nb
return(oDes)
}
#
# t <- 1; tMin <- 1e-5; c <- 0.7; L <- 10000; l <- 1
# t <- 1; tMin <- 1e-5; c <- 0.8; L <- 25000; l <- 1
# t <- 1; tMin <- 1e-5; c <- 0.9; L <- 50000; l <- 1
t <- 1; tMin <- 1e-7; c <- 0.9; L <- 100000; l <- 1
#
fitInc <- fit(inc, dat.ib, dat.bib)
best <- list(inc, fitInc)
vers <- versBest <- 1
#
start <- Sys.time()
while(t > tMin){
while(l < L){
thisBl <- (l - 1) %% nBl + 1
# Perturbation
child <- inc
items.raus <- which(child[, thisBl] == 1)
raus <- sample(items.raus, 1)
bibPaar.bl <- dat.bibPaare[thisBl, ] != 0
items.bibPaare <- rowSums(child[, bibPaar.bl]) > 0
rein <- which(!items.bibPaare)
if(thisBl %in% blMatching){
rein <- sample(intersect(rein, itemsMatching), 1)
}else{
rein <- sample(intersect(rein, itemsSonst), 1)
}
child[c(raus, rein), thisBl] <- c(0, 1)
# Fit und Survival
fitChild <- fit(child, dat.ib, dat.bib)
behalte <- fitChild < fitInc
if(!behalte){
pt <- exp((fitInc - fitChild) / t)
behalte <- runif(1) <= pt
}
if(behalte){
inc <- child
fitInc <- fitChild
}
if(fitInc < best[[2]]){
best <- list(inc, fitInc)
versBest <- versBest + 1
}
# Kontroll-Ausgaben; ggf. löschen
if (identical(inc, child)) vers <- vers + 1
if (l %% 500 == 0) {
cat("\r")
cat(paste("l=", l),
paste("t=", as.integer(log(t) / log(c) + 1)),
paste("versionen=", vers),
paste("versionenBest=", versBest),
paste("fit=", round(fitInc, 4)),
paste("fitBest=", round(best[[2]], 4)),
paste("pt=", round(pt, 5)),
sep="; ")
cat(" ")
flush.console()
}
l <- l + 1
}
l <- 1
t <- t * c
}
end <- Sys.time()
## End(Not run)
Kapitel 6: Skalierung und Linking
Description
Das ist die Nutzerseite zum Kapitel 6, Skalierung und Linking, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Author(s)
Matthias Trendtel, Giang Pham, Takuya Yanagida
References
Trendtel, M., Pham, G. & Yanagida, T. (2016). Skalierung und Linking. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 185–224). Wien: facultas.
See Also
Zu datenKapitel06
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 5
, Testdesign.
Zu Kapitel 7
, Statistische Analysen produktiver Kompetenzen.
Zur Übersicht
.
Examples
## Not run:
library(TAM)
library(sirt)
library(WrightMap)
library(miceadds)
library(plyr)
set.seed(20150528)
dat <- data(datenKapitel06)
# Hauptstudie
dat <- datenKapitel06$dat
ue <- datenKapitel06$itembank
items <- grep("I", colnames(dat), value=TRUE)
# Nur TH1
datTH1 <- datenKapitel06$datTH1
ueTH1 <- datenKapitel06$itembankTH1
rownames(ueTH1) <- ueTH1$Item
itemsTH1 <- grep("I", colnames(datTH1), value=TRUE)
respTH1 <- datTH1[, -(1:4)]; wTH1 <- datTH1$wgtstud
# Normierungsstudie
normdat <- datenKapitel06$normdat
## -------------------------------------------------------------
## Abschnitt 6.3.4 Das Partial Credit Model (PCM)
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 1: Leistungsdaten und Stich-
# probengewichte Objekten zuweisen
#
resp <- dat[, grep("I", colnames(dat))]; w <- dat$wgtstud
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 2: Anpassen eines PCMs
#
mod.1PL <- tam.mml(resp = resp, irtmodel = "1PL", pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 2a: Ergänzung zum Buch
# Runden zur besseren Darstellung im Buch
#
mod.1PL$item$M <- round(mod.1PL$item$M, 2)
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 3: Darstellung des letzen Items
#
tail(mod.1PL$item, 1)
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 4: Umparametrisierung
#
b_ih <- mod.1PL$item[, grep("AXsi_", colnames(mod.1PL$item))]
delta.tau <- pcm.conversion(b_ih)
# -------------------------------------------------------------
# Abschnitt 6.3.4, Listing 5: Berechnung der Thursonian
# Threshods und Lokations Indizes
#
thurst.thres <- IRT.threshold(mod.1PL)
LI <- IRT.threshold(mod.1PL, type="item")
## -------------------------------------------------------------
## Abschnitt 6.3.5 Itemtrennschärfen polytomer Items und
## Rateparameter
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 1: Anpassen eines Generalized
# Partial Credit Models
#
mod.GPCM <- tam.mml.2pl(resp, irtmodel = "GPCM", pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 2: Anpassen eines
# Nominal Item Response Models
#
mod.NIRM <- tam.mml.2pl(resp, irtmodel="2PL", pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 3: Anpassen eines Generalized
# Partial Credit Models mit festen
# Itemgewichten (Trennschärfen)
#
tammodel <- "
LAVAAN MODEL:
F =~ a1__a50*I1__I50;
# Trait-Varianz auf 1 fixieren
F ~~ 1*F
MODEL CONSTRAINT:
# Gewichtung für die Items festlegen
a1__a40 == 1*a # dichotome Items
a41__a44 == .3333*a # T/F Items mit max. Score von 3
a45__a50 == .25*a # M56 Items mit max. Score von 4
"
mod.GPCMr <- tamaan(tammodel, resp, pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 4: Itemtrennschärfevergleich
#
## Itemparameter im Vergleich
rbind(GPCM = mod.GPCM$item[50, 9:12],
NIRM = mod.NIRM$item[50, 9:12],
GPCMr = mod.GPCMr$item[50, 10:13]) / rep(c(1:4), each=3)
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 5: Itemtrennschärfen eines
# dichotomen und eines polytomen
# Items
rbind(I40 = mod.GPCMr$item[40, 10:13],
I50 = mod.GPCMr$item[50, 10:13])
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 6: Anpassen eines 1PL-G Modells
#
## Das 1PL-G Modell
tammodel <- "
LAVAAN MODEL:
F =~ 1*I1__I50
F ~~ F
# Rateparameter für MC4 Items
I1__I10 ?= gMC4*g1
# Rateparameter für MC3 Items
I11__I20 + I31__I40 ?= gMC3*g1
"
mod.1PL_G <- tamaan(tammodel, resp, pweights = w,
control = list(Msteps = 15))
# -------------------------------------------------------------
# Abschnitt 6.3.5, Listing 7: Ausgabe geschätzter Rateparameter
# für MC3 und MC4 Items
#
mod.1PL_G$item[c(10,11), c(1,4,5)]
## -------------------------------------------------------------
## Abschnitt 6.3.6 Bookleteffekte
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.3.6, Listing 1: Anpassen eines Bookletmodells
#
mod.1PL_Book <- tam.mml.mfr(resp, facets = cbind(th = dat$th),
formulaA= ~ item + item:step + th, pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.3.6, Listing 2: Ausgabe der Bookleteffekte der einzelnen
# Testhefte
#
rbind((tmp <- mod.1PL_Book$xsi[paste0("thER0", 1:5),]),
thER06 = - c(sum(tmp[,1]), NA))
## -------------------------------------------------------------
## Abschnitt 6.3.7 Personenfähigkeitsschätzer
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 1: WLEs
#
WLE.1PL <- as.data.frame(tam.wle(mod.1PL))
round(head(WLE.1PL, 2), 4)
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 2: WLE Reliabilität
#
WLErel(WLE.1PL$theta, WLE.1PL$error, w)
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 3: EAPs
#
round(head(mod.1PL$person, 2), 4)
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 4: EAP Reliabilität
#
EAPrel(mod.1PL$person$EAP, mod.1PL$person$SD.EAP, w)
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 4a: Ergänzung zum Buch
# Alternative Berechnung der EAP-Reliabilität
#
1 - weighted.mean(mod.1PL$person$SD.EAP^2, w)/mod.1PL$variance
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 5: PVs
#
PV.1PL <- tam.pv(mod.1PL)$pv
round(head(PV.1PL, 2), 4)
# -------------------------------------------------------------
# Abschnitt 6.3.7, Listing 6: Statistische Kennwerte der einzelnen
# Personenfähigkeitsschätzer
#
cbind(WLEs = c(M = weighted.mean(WLE.1PL$theta, w),
SD = weighted_sd(WLE.1PL$theta, w)),
EAPs = c(M = weighted.mean(mod.1PL$person$EAP, w),
SD = weighted_sd(mod.1PL$person$EAP, w)),
PVs = c(M = mean(apply(PV.1PL[, -1], 2, weighted.mean, w)),
SD=mean(apply(PV.1PL[, -1], 2, weighted_sd, w))))
## -------------------------------------------------------------
## Abschnitt 6.3.8 Mehrdimensionale Modelle
## -------------------------------------------------------------
# Achtung: Algorithmen benötigen einige Zeit
# Zur schnelleren Konvergenz werden nur Daten aus Testheft 1 verwendet
# -------------------------------------------------------------
# Abschnitt 6.3.8, Listing 1: Verteilung der Items auf Foki
#
table(paste("Fokus", ue$focus[ue$Item %in% colnames(datTH1)]))
table(paste("Fokus", ueTH1$focus))
# -------------------------------------------------------------
# Abschnitt 6.3.8, Listing 2: Spezifizierung der Q-Matrix und
# Anpassung des Modells
# Achtung: Schätzung benötigt > 300 Iterationen
#
Q <- array(0, c(25, 5), list(items[items %in% colnames(datTH1)]))
for(i in 1:25) Q[i, ueTH1$focus[i] + 1] <- 1
mod.1PL_multi <- tam(resp = respTH1, pweights = wTH1,
Q = Q, control = list(snodes = 1500))
# -------------------------------------------------------------
# Abschnitt 6.3.8, Listing 3: Anpassen eines Bifaktormodells
# Achtung: Schätzung benötigt > 350 Iterationen
#
mod.1PL_bi <- tam.fa(respTH1, irtmodel = "bifactor1",
dims = ueTH1$format, pweights = wTH1,
control = list(snodes = 1500))
# -------------------------------------------------------------
# Abschnitt 6.3.8, Listing 4: Darstellung der Varianzen des
# Hauptfaktors und der Störfaktoren
#
nams <- c("I26", "I45", "I12", "I1", "I41")
dfr <- data.frame(mod.1PL_bi$B.stand[nams,],
row.names=ueTH1[nams, "format"])
dfr
# -------------------------------------------------------------
# Abschnitt 6.3.8, Listing 5: Darstellung der Reliabilitätsschätzer
#
mod.1PL_bi$meas
## -------------------------------------------------------------
## Abschnitt 6.3.9 Modellpassung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.3.9, Listing 1: Berechnung und Darstellungen von
# Itemfitstatistiken
#
itemfit <- tam.fit(mod.1PL)
summary(itemfit)
# -------------------------------------------------------------
# Abschnitt 6.3.9, Listing 2: Berechnung und Darstellungen von
# Modellfitstatistiken
#
modfit <- tam.modelfit(mod.1PL)
modfit$fitstat
# -------------------------------------------------------------
# Abschnitt 6.3.9, Listing 3: LRT für Modelltestung
#
anova(mod.1PL, mod.GPCM)
## -------------------------------------------------------------
## Abschnitt 6.4.1 Simultane Kalibrierung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.4.1, Listing 1: Daten vorbereiten
#
vars <- c("idstud", "wgtstud", "th")
# Daten der Hauptstudie
tmp1 <- cbind("Hauptstudie" = 1, dat[,c(vars, items)])
# Daten der Normierungsstudie
n.items <- grep("I|J",names(normdat),value=T)
tmp2 <- cbind("Hauptstudie" = 0, normdat[, c(vars, n.items)])
# Schülergewichte der Normierungsstudie sind konstant 1
# Datensätze zusammenfügen
dat.g <- rbind.fill(tmp1,tmp2)
all.items <- grep("I|J",names(dat.g),value=T)
# -------------------------------------------------------------
# Abschnitt 6.4.1, Listing 2: Simultane Kalibrierung
# Achtung: Schätzung benötigt > 450 Iterationen
#
# 2-Gruppenmodell
linkmod1 <- tam.mml(resp=dat.g[, all.items], pid=dat.g[, 2],
group = dat.g$Hauptstudie, pweights=dat.g$wgtstud)
summary(linkmod1)
# -------------------------------------------------------------
# Abschnitt 6.4.1, Listing 2a: Ergänzung zum Buch
# Berechnung von Verteilungsparametern
#
set.seed(20160828)
# PVs
PV_linkmod1 <- tam.pv(linkmod1, nplausible = 20)
# Personendatensatz
dfr_linkmod1 <- linkmod1$person
dfr_linkmod1 <- merge( x = dfr_linkmod1, y = PV_linkmod1$pv, by = "pid" , all=T)
dfr_linkmod1 <- dfr_linkmod1[ order(dfr_linkmod1$case) , ]
# Leistungsskala transformieren
vars.pv <- grep("PV",names(dfr_linkmod1),value=T)
# Mittlere Fähigkeit der Normierungsgruppe
p0 <- which(dat.g$Hauptstudie == 0)
M_PV <- mean(apply(dfr_linkmod1[p0,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_linkmod1[p0,"pweight"]))
SD_PV <- mean(sqrt(apply(dfr_linkmod1[p0,vars.pv],2,Hmisc::wtd.var,
weights = dfr_linkmod1[p0,"pweight"])))
# Tranformationsparameter
a <- 100/SD_PV; b <- 500 - a*M_PV
# Verteilungsparameter der Hauptstudie
p1 <- which(dat.g$Hauptstudie == 1)
M1_PV <- mean(apply(dfr_linkmod1[p1,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_linkmod1[p1,"pweight"]))
SD1_PV <- mean(sqrt(apply(dfr_linkmod1[p1,vars.pv],2,Hmisc::wtd.var,
weights = dfr_linkmod1[p1,"pweight"])))
TM_PV <- M1_PV*a + b; TSD_PV <- SD1_PV*a
# Ergebnisse
trafo_linkmod1 <- data.frame(M_Norm = 500, SD_Norm = 100, a = a, b = b,
M = TM_PV, SD = TSD_PV)
## -------------------------------------------------------------
## Abschnitt 6.4.2 Separate Kalibrierung mit fixiertem
## Itemparameter
## -------------------------------------------------------------
# Vorgehensweise 1:
# Daten der Normierungsstudie frei kalibrieren und skalieren
# Skalierung der Hauptstudie-Daten mit fixiertem Itemparameter
# -------------------------------------------------------------
# Abschnitt 6.4.2, Listing 1: Daten der Normierungsstudie frei
# kalibrieren und skalieren
#
normmod <- tam.mml(resp = normdat[, n.items],
pid = normdat[, "idstud"])
# -------------------------------------------------------------
# Abschnitt 6.4.2, Listing 1a: Ergänzung zum Buch
# Berechnung von Verteilungsparametern
#
summary(normmod)
set.seed(20160828)
# Personenfähigkeitsschätzer
PV_normmod <- tam.pv(normmod, nplausible = 20)
# In Personendatensatz kombinieren
dfr_normmod <- normmod$person
dfr_normmod <- merge( x = dfr_normmod, y = PV_normmod$pv, by = "pid" , all=T)
dfr_normmod <- dfr_normmod[ order(dfr_normmod$case) , ]
M_norm <- mean(apply(dfr_normmod[,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_normmod[,"pweight"]))
SD_norm <- mean(sqrt(apply(dfr_normmod[,vars.pv],2,Hmisc::wtd.var,
weights = dfr_normmod[,"pweight"])))
# Tranformationsparameter
a_norm <- 100/SD_norm; b_norm <- 500 - a_norm*M_norm
TM_norm <- M_norm * a_norm + b_norm
TSD_norm <- SD_norm * a_norm
# -------------------------------------------------------------
# Abschnitt 6.4.2, Listing 2: Parameter aus Normierungsstudie
# für die Skalierung der Haupt-
# studie bei deren Skalierung
# fixieren
#
# Itemschwierigkeit aus der Normierungsstudie
norm.xsi <- normmod$xsi.fixed.estimated
# Hauptstudie: xsi-Matrix aus mod.1PL
xsi.fixed <- mod.1PL$xsi.fixed.estimated
# nur Parameter von Items in Hauptstudie
norm.xsi <- norm.xsi[
rownames(norm.xsi) %in% rownames(xsi.fixed), ]
# Setzen der Parameter in richtiger Reihenfolge
xsi.fixed <- cbind(match(rownames(norm.xsi),
rownames(xsi.fixed)), norm.xsi[, 2])
# Skalierung der Hauptstudie-Daten mit fixierten Itemparameter
mainmod.fixed <- tam.mml(resp = resp, xsi.fixed = xsi.fixed,
pid = dat$MB_idstud, pweights = w)
# -------------------------------------------------------------
# Abschnitt 6.4.2, Listing 2a: Ergänzung zum Buch
# Berechnung von Verteilungsparametern
#
summary(mainmod.fixed)
set.seed(20160828)
# Personenfähigkeitsschätzer
WLE_mainmod.fixed <- tam.wle(mainmod.fixed)
PV_mainmod.fixed <- tam.pv(mainmod.fixed, nplausible = 20)
# In Personendatensatz kombinieren
dfr_mainmod.fixed <- mainmod.fixed$person
dfr_mainmod.fixed <- merge( x = dfr_mainmod.fixed, y = WLE_mainmod.fixed, by = "pid" , all=T)
dfr_mainmod.fixed <- merge( x = dfr_mainmod.fixed, y = PV_mainmod.fixed$pv, by = "pid" , all=T)
dfr_mainmod.fixed <- dfr_mainmod.fixed[ order(dfr_mainmod.fixed$case) , ]
M_main <- mean(apply(dfr_mainmod.fixed[,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_mainmod.fixed[,"pweight"]))
SD_main <- mean(sqrt(apply(dfr_mainmod.fixed[,vars.pv],2,Hmisc::wtd.var,
weights = dfr_mainmod.fixed[,"pweight"])))
TM_main <- M_main * a_norm + b_norm
TSD_main <- SD_main * a_norm
trafo.fixed1 <- data.frame(M_norm = M_norm, SD_norm = SD_norm,
a = a_norm, b = b_norm,
TM_norm = TM_norm, TSD_norm = TSD_norm,
M_PV = M_main, SD_PV = SD_main,
M_TPV = TM_main, SD_TPV = TSD_main)
# Vorgehensweise 2:
# Daten der Hauptstudie frei kalibrieren und skalieren
# Skalierung der Hauptstudie-Daten mit fixierten Itemparameter
# -------------------------------------------------------------
# Abschnitt 6.4.2, Listing 2b: Ergänzung zum Buch
# Analoges Vorgehen mit fixierten Parametern aus der
# Hauptstudie für die Skalierung der Normierungsstudie
#
# Daten der Hauptstudie kalibrieren und skalieren
mainmod <- tam.mml(resp=dat[, items], irtmodel="1PL",
pid=dat$MB_idstud, pweights=dat[,"wgtstud"])
summary(mainmod)
set.seed(20160828)
# Personenfähigkeitsschätzer
WLE_mainmod <- tam.wle(mainmod)
PV_mainmod <- tam.pv(mainmod, nplausible = 20)
# In Personendatensatz kombinieren
dfr_mainmod <- mainmod$person
dfr_mainmod <- merge( x = dfr_mainmod, y = WLE_mainmod, by = "pid" , all=T)
dfr_mainmod <- merge( x = dfr_mainmod, y = PV_mainmod$pv, by = "pid" , all=T)
dfr_mainmod <- dfr_mainmod[order(dfr_mainmod$case),]
M_main <- mean(apply(dfr_mainmod[,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_mainmod[,"pweight"]))
SD_main <- mean(sqrt(apply(dfr_mainmod[,vars.pv],2,Hmisc::wtd.var,
weights = dfr_mainmod[,"pweight"])))
# Itemschwierigkeit aus der Hauptstudie
main.xsi <- mod.1PL$xsi.fixed.estimated
# Hauptstudie: xsi-Matrix aus normmod
xsi.fixed <- normmod$xsi.fixed.estimated
# nur Parameter von Items in Hauptstudie
main.xsi <- main.xsi[
rownames(main.xsi) %in% rownames(xsi.fixed), ]
# Setzen der Parameter in richtiger Reihenfolge
xsi.fixed <- cbind(match(rownames(main.xsi),
rownames(xsi.fixed)), main.xsi[, 2])
# Skalierung der Hauptstudie-Daten mit fixiertem Itemparameter
normmod.fixed <- tam.mml(resp=normdat[, n.items], irtmodel="1PL",
xsi.fixed = xsi.fixed,
pid=normdat$MB_idstud, pweights=normdat[,"wgtstud"])
summary(normmod.fixed)
set.seed(20160828)
# Personenfähigkeitsschätzer
PV_normmod.fixed <- tam.pv(normmod.fixed, nplausible = 20)
dfr_normmod.fixed <- normmod.fixed$person
dfr_normmod.fixed <- merge( x = dfr_normmod.fixed, y = PV_normmod.fixed$pv, by = "pid" , all=T)
dfr_normmod.fixed <- dfr_normmod.fixed[ order(dfr_normmod.fixed$case) , ]
M_norm <- mean(apply(dfr_normmod.fixed[,vars.pv],2,Hmisc::wtd.mean,
weights = dfr_normmod.fixed[,"pweight"]))
SD_norm <- mean(sqrt(apply(dfr_normmod.fixed[,vars.pv],2,Hmisc::wtd.var,
weights = dfr_normmod.fixed[,"pweight"])))
# Tranformationsparameter
a_norm <- 100/SD_norm; b_norm <- 500 - a_norm*M_norm
TM_norm <- M_norm * a_norm + b_norm
TSD_norm <- SD_norm * a_norm
TM_main <- M_main * a_norm + b_norm
TSD_main <- SD_main * a_norm
trafo.fixed2 <- data.frame(M_PV = M_main, SD_PV = SD_main,
M_Norm.fixed = M_norm, SD_Norm.fixed = SD_norm,
a = a_norm, b = b_norm,
TM_norm = TM_norm, TSD_norm = TSD_norm,
M_TPV = TM_main, SD_TPV = TSD_main)
## -------------------------------------------------------------
## Abschnitt 6.4.3 Separate Kalibrierung mit Linking durch
## Transformationsfunktion
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.4.3, Listing 1: equating.rasch()
#
# Freigeschätzte Itemparameter der Normierung- und Hauptstudie
norm.pars <- normmod$item[,c("item","xsi.item")]
main.pars <- mainmod$item[,c("item","xsi.item")]
# Linking mit equating.rasch
mod.equate <- equating.rasch(x = norm.pars, y = main.pars)
mod.equate$B.est
# Mean.Mean Haebara Stocking.Lord
# -0.1798861 -0.1788159 -0.1771145
head(mod.equate$anchor,2)
# -------------------------------------------------------------
# Abschnitt 6.4.3, Listing 1a: Ergänzung zum Buch
# Berechnung Linkingfehler
#
linkitems <- intersect(n.items, items)
head(mod.equate$transf.par,2)
mod.equate$descriptives
# Linkingfehler: Jackknife unit ist Item
pars <- data.frame(unit = linkitems,
study1 = normmod$item$xsi.item[match(linkitems, normmod$item$item)],
study2 = mainmod$item$xsi.item[match(linkitems, mainmod$item$item)],
item = linkitems)
# pars <- as.matrix(pars)
mod.equate.jk <- equating.rasch.jackknife(pars,se.linkerror = T)
mod.equate.jk$descriptives
# -------------------------------------------------------------
# Abschnitt 6.4.3, Listing 2: Linking nach Haberman
#
# Itemparameter der Normierungsstudie
M1 <- mean( apply(dfr_normmod[,vars.pv], 2, mean ) )
SD1 <- mean( apply(dfr_normmod[,vars.pv], 2, sd ) )
a1 <- 1/SD1; b1 <- 0-a1*M1
A <- normmod$item$B.Cat1.Dim1/a1
B <- (normmod$item$xsi.item + b1/a1)
# Itemparameter der Normierungsstudie fuer haberman.linking
tab.norm <- data.frame(Studie = "1_Normierung",
item = normmod$item$item,
a = A, b = B/A)
# Itemparameter der Hauptstudie
A <- mainmod$item$B.Cat1.Dim1
B <- mainmod$item$xsi.item
tab.main <- data.frame(Studie = "2_Hauptstudie",
item = mainmod$item$item,
a = A, b = B/A)
# Itemparameter aller Studien
itempars <- rbind(tab.norm, tab.main)
# Personenparameter
personpars <- list(PV_normmod$pv*a1+b1, PV_mainmod$pv)
# Linking nach Habermans Methode
linkhab <- linking.haberman(itempars = itempars,
personpars = personpars)
# -------------------------------------------------------------
# Abschnitt 6.4.3, Listing 2a: Ergänzung zum Buch
# Ergebnisdarstellung, Transformation und Berechnung
# von Verteilungsparametern
#
# Ergebnisse
# Transformationsparameter der Itemparameter
linkhab$transf.itempars
# Transformationsparameter der Personenparameter
linkhab$transf.personpars
# Itemparameter
dfr.items <- data.frame(linkhab$joint.itempars,
linkhab$b.orig, linkhab$b.trans)
names(dfr.items)[-1] <- c("joint_a","joint_b",
"orig_b_norm","orig_b_main",
"trans_b_norm","trans_b_main")
head(round2(dfr.items[,-1],2),2)
# Transformierte Personenparameter der Hauptstudie
dfr_main_transpv <- linkhab$personpars[[2]]
names(dfr_main_transpv)[-1] <- paste0("linkhab_",vars.pv)
dfr_main_transpv <- cbind(dfr_mainmod,dfr_main_transpv[,-1])
round2(head(dfr_main_transpv[,c("PV1.Dim1","linkhab_PV1.Dim1","PV2.Dim1","linkhab_PV2.Dim1")],2),2)
# Aufgeklärte und Fehlvarianz des Linkings
linkhab$es.invariance
# Transformationsparameter der Normierungsstudie auf Skala 500,100
# trafo.fixed1
a <- 100/mean( apply(dfr_normmod[,vars.pv]*a1+b1, 2, sd ) )
b <- 500 - a*mean( apply(dfr_normmod[,vars.pv]*a1+b1, 2, mean ) )
# trafo.fixed2
M_PV <- mean( apply(linkhab$personpars[[2]][vars.pv], 2,
Hmisc::wtd.mean, weights = dfr_mainmod$pweight ) )
SD_PV <- mean( sqrt(apply(linkhab$personpars[[2]][vars.pv], 2,
Hmisc::wtd.var, weights = dfr_mainmod$pweight )) )
M_TPV <- M_PV*a + b
SD_TPV <- SD_PV * a
trafo.linkhab <- data.frame(trafo.fixed1[,1:2],
a1 = a1, b1 = b1,
M_norm_trans = 0,
SD_norm_trans = 1,
a = 100, b = 500,
trafo.fixed2[,1:2],
linkhab_M_PV = M_PV,
linkhab_SD_PV = SD_PV,
linkhab_M_TPV = M_TPV,
linkhab_SD_TPV = SD_TPV)
## -------------------------------------------------------------
## Abschnitt 6.4.4 Ergebnisse im Vergleich und Standardfehler
## des Linkings
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 6.4.4, Listing 3a: Ergänzung zum Buch
# Berechnung von Standardfehlern Ergebnisvergleiche
#
# Gemeinsame Skalierung mit fixiertem Itemparameter aus Hauptstudie
# Standardfehler bzgl. Itemstichprobenfehler
# Matrix für fixerte Itemparameter vorbereiten
xsi.fixed <- normmod.fixed$xsi.fixed.estimated
npar <- length(xsi.fixed[,"xsi"])
mat.xsi.fixed <- cbind(index=1:npar,par = dimnames(xsi.fixed)[[1]])
sequence <- match(mat.xsi.fixed[,"par"],dimnames(main.xsi)[[1]])
mat.xsi.fixed <- cbind(index=as.numeric(mat.xsi.fixed[,1]),
par = mat.xsi.fixed[,2],
xsi.fixed = as.numeric(main.xsi[sequence,"xsi"]))
# Nicht fixierte Itemparameter löschen
del <- which(is.na(mat.xsi.fixed[,"xsi.fixed"]))
mat.xsi.fixed <- mat.xsi.fixed[-del,]
head(mat.xsi.fixed,3)
dfr <- data.frame(elim = "none",growth=trafo.fixed2$M_TPV-500)
# Jedes Mal ein Ankeritem weniger
# Schleife über alle Ankeritems
set.seed(20160828)
for(ii in linkitems){
# ii <- linkitems[1]
del <- grep(paste0(ii,"_"), mat.xsi.fixed[,2])
tmp <- mat.xsi.fixed[-del,c(1,3)]
tmp <- data.frame(index = as.numeric(tmp[,1]),xsi.fixed = as.numeric(tmp[,2]))
# Skalierung der Hauptstudie-Daten mit fixiertem Itemparameter
normmod.tmp <- tam.mml(resp=normdat[, n.items], irtmodel="1PL",
xsi.fixed = tmp,
pid=normdat$MB_idstud, pweights=normdat[,"wgtstud"])
# Personenfähigkeitsschätzer
# WLE_normmod.tmp <- tam.wle(normmod.tmp)
PV_normmod.tmp <- tam.pv(normmod.tmp, nplausible = 20)
# In Personendatensatz kombinieren
M_norm.tmp <- mean(apply(PV_normmod.tmp$pv[,vars.pv],2,mean))
SD_norm.tmp <- mean(apply(PV_normmod.tmp$pv[,vars.pv],2,sd))
# Tranformationsparameter
a_norm.tmp <- 100/SD_norm.tmp
b_norm.tmp <- 500 - a_norm.tmp*M_norm.tmp
TM_main.tmp <- M_main * a_norm.tmp + b_norm.tmp
dfr.tmp <- data.frame(elim = ii,growth=TM_main.tmp-500)
dfr <- rbind(dfr,dfr.tmp)
}
dfr$diff2 <- (dfr$growth-dfr$growth[1])^2
sum <- sum(dfr$diff2)
Var <- sum*28/29
SE <- sqrt(Var)
quant <- 1.96
low <- trafo.fixed2$M_TPV - quant*SE
upp <- trafo.fixed2$M_TPV + quant*SE
dfr$SE <- SE; dfr$quant <- quant
dfr$low <- low; dfr$upp <- upp
## End(Not run)
Kapitel 7: Statistische Analysen produktiver Kompetenzen
Description
Das ist die Nutzerseite zum Kapitel 7, Statistische Analysen produktiver Kompetenzen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Abschnitt 1: Beispieldatensätze
Der zur Illustration verwendete Datensatz prodRat
beinhaltet die
beurteilten Schreibkompetenzen im Fach Englisch auf der 8. Schulstufe von 9836
Schüler/innen (idstud
) die von insgesamt 41 Ratern (rater
)
beurteilt wurden.
Die sechs Schreibaufgaben (aufgabe
) wurden auf sechs Testhefte
(th
) aufgeteilt, wobei jede Aufgabe in genau zwei Testheften vorkommt.
Zur weiteren Analyse verwenden wir auch den Datensatz prodPRat
mit
sogenannten Pseudoratern.
Für die Analyse von Varianzkomponenten mittels Linear Mixed Effects (LME)
Modellen verwenden wir den ursprünglichen Datensatz im Long Format
(prodRatL
).
Abschnitt 2: Beurteilerübereinstimmung
Listing 1: Berechnen von Häufigkeitstabellen
Hier werden die Datensätze prodRat
und prodPRat
verwendet.
Die R-Funktion apply()
ermöglicht eine Anwendung einer beliebigen
Funktion z.B. prop.table()
über alle Zeilen (1) oder Spalten (2) eines
data.frame
.
library(irr)
data(datenKapitel07)
prodRat <- datenKapitel07$prodRat
# Items auswählen
items <- c("TA", "CC", "GR", "VO")
# Tabelle erzeugen
tab <- apply(prodRat[, items], 2,
FUN=function(x){
prop.table(table(x))*100})
print(tab, digits = 2)
# Mittelwert der Ratings berechnen
round(apply(prodRat[, items], 2, mean), 2)
Listing 2: Beurteilerübereinstimmung berechnen
Wir verwenden den Datensatz mit Pseudoratern prodPRat
.
Die Analysen werden mit dem Paket irr
durchgeführt.
prodRat <- datenKapitel07$prodRat
items <- c("TA", "CC", "GR", "VO")
dfr <- data.frame(items, agree = NA,
kappa = NA, wkappa = NA, korr = NA)
for(i in 1:length(items)){
dat.i <- prodPRat[, grep(items[i], colnames(prodPRat))]
dfr[i, "agree"] <- agree(dat.i, tolerance = 1)["value"]
dfr[i, "kappa"] <- kappa2(dat.i)["value"]
dfr[i, "wkappa"] <- kappa2(dat.i, weight = "squared")["value"]
dfr[i, "korr"] <- cor(dat.i[,1], dat.i[,2])
dfr[i, "icc"] <- icc(dat.i, model = "twoway")["value"]
}
print(dfr, digits = 3)
Abschnitt 3: Skalierungsmodelle
Listing 1: Skalierungsmodell mit TAM
Der Funktion tam.mm.mfr()
muss ein data.frame
für die Facetten
übergeben werden.
Zusätzlich können Einstellungen in einer Liste für das Argument
control = list()
übergeben werden.
Hier verwenden wir die Einstellung xsi.start0 = 1
, was dazu führt, dass
alle Startwerte auf 0 gesetzt werden.
Mit fac.oldxsi = 0.1
setzen wir das Gewicht der Parameterwerte aus der
vorigen Iteration etwas über 0.
Damit kann der Algorithmus stabilisiert und Konvergenzprobleme (deviance
increase) verhindert werden. Wir definieren noch increment.factor = 1.05
etwas über dem default-Wert von 1 um mögliche Konvergenzprobleme abzufangen.
Dieser Wert definiert das Ausmaß der Abnahme des maximalen Zuwachs der
Parameter pro Iteration (s. TAM-Hilfe).
Die Personenparameter werden mit der Funktion tam.wle()
geschätzt.
Gibt man in der Funktion summary()
das Argument file
an, so wird
der Output direkt in ein Textfile geschrieben.
set.seed(1234)
library(TAM)
prodRat <- datenKapitel07$prodRat
# Rater-Facette definieren
facets <- prodRat[, "rater", drop = FALSE]
# Response Daten definieren
vars <- c("TA", "CC", "GR", "VO")
resp <- prodRat[, vars]
# Personen-ID definieren
pid <- prodRat$idstud
# Formel für Modell
formulaA <- ~item*step+item*rater
# Modell berechnen
mod <- tam.mml.mfr(resp = resp, facets = facets, formulaA = formulaA,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
summary(mod, file="TAM_MFRM")
# Personenparameter und Rohscores
persons.mod <- tam.wle(mod)
persons.mod$raw.score <- persons.mod$PersonScores / (persons.mod$N.items)
Listing 1b (Ergänzung zum Buch): Skalierungsmodell mit TAM
Hier werden alle im Buch besprochenen Modelle berechnet und anschließend ein Modellvergleich durchgeführt.
f1 <- ~item * rater * step
mod1 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f1,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f2 <- ~item*step+item*rater
mod2 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f2,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f3 <- ~item * step + rater
mod3 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f3,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f4 <- ~item + step + rater
mod4 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f4,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
mod4$xsi.facets
IRT.compareModels(mod1, mod2, mod3, mod4)
Listing 1c (Ergänzung zum Buch): Wright-Map
Mit dem Paket WrightMap
können die Ergebnisse für die einzelnen Facetten
dargestellt werden. Wir machen dies für Items und Rater.
library(WrightMap)
item.labs <- vars
rater.labs <- unique(prodRat$rater)
item.labs <- c(item.labs, rep(NA, length(rater.labs) -
length(item.labs)))
pars <- mod$xsi.facets$xsi
facet <- mod$xsi.facets$facet
item.par <- pars[facet == "item"]
rater.par <- pars[facet == "rater"]
item_rat <- pars[facet == "item:rater"]
len <- length(item_rat)
item.long <- c(item.par, rep(NA, len - length(item.par)))
rater.long <- c(rater.par, rep(NA, len - length(rater.par)))
wrightMap(persons.mod$theta, rbind(item.long, rater.long),
label.items = c("Items", "Rater"),
thr.lab.text = rbind(item.labs, rater.labs),
axis.items = "", min.l=-3, max.l=3,
axis.persons = "Personen")
Listing 2: Fit-Indices berechnen
Die Fit-Indices werden mit der Funktion msq.itemfitWLE
für die
Raterparameter und Itemparameter gesondert berechnet.
Der Funktion muss ein Vektor mit Parameterbezeichnungen übergeben werden so wie
sie im Modell-Objekt vorkommen.
Im Paket TAM
gibt es noch die Funktion tam.fit()
, diese basiert
auf einer Simulation der individuellen Posterior-Verteilung.
Die Funktion msq.itemfitWLE
wertet dagegen die individuelle
Posterior-Verteilung direkt aus (s. TAM
-Hilfe für weitere Beispiele) und
führt keine Simulation durch.
# Infit/Outfit berechnen
pseudo_items <- colnames(mod$resp)
pss <- strsplit(pseudo_items , split="-")
item_parm <- unlist(lapply(pss, FUN = function(ll){ll[1]}))
rater_parm <- unlist(lapply(pss, FUN = function(ll){ll[2]}))
# Fit Items
res.items <- msq.itemfitWLE(mod, item_parm)
summary(res.items)
# Fit Rater
res.rater <- msq.itemfitWLE(mod, rater_parm)
summary(res.rater)
Listing 2a (Ergänzung zum Buch): Abbildung Fit-Indices
# Abbildung: Histogramm, Rohscores
par(mfcol=c(1,2))
hist(persons.mod$theta, col="grey", breaks=40,
main = "",
xlab = "Theta (logits)",
ylab = "Häufigkeit")
with(persons.mod, scatter.smooth(raw.score, theta,
pch = 1, cex = .6, xlab = "Roscores",
ylab = "Theta (logits)",
lpars = list(col = "darkgrey", lwd = 2, lty = 1)))
# Abbildung: Fit-Statistik
par(mfcol=c(1,2))
fitdat <- res.rater$fit_data
fitdat$var <- factor(substr(fitdat$item, 1, 2))
boxplot(Outfit~var, data=fitdat,
ylim=c(0,2), main="Outfit")
boxplot(Infit~var, data=fitdat,
ylim=c(0,2), main="Infit")
Listing 2b (Ergänzung zum Buch): Korrelationen
Pearson und Spearman Korrelationskoeffizient wird zwischen Rohscores und Theta berechnet.
korr <- c(with(persons.mod, cor(raw.score, theta,
method = "pearson")),
with(persons.mod, cor(raw.score, theta,
method = "spearman")))
print(korr)
Listing 3: Q3-Statistik berechnen
Die Q3-Statistik für lokale stochastische Unabhängigkeit wird mit der Funktion
tam.modelfit()
berechnet.
Der Output enthält eine Vielzahl an Fit-Statistiken, für weitere Details sei
hier auf die TAM
-Hilfeseite verwiesen.
Die adjustierte aQ3-Statistik berechnet sich aus den Q3-Werten abzüglich des
Gesamtmittelwerts von allen Q3-Werten.
Mit tam.modelfit()
werden Fit-Statistiken für alle Rater x Item
Kombinationen berechnet.
Diese werden im Code unten anschließend aggregiert um eine Übersicht zu
erhalten.
Dazu werden zuerst nur Paare gleicher Rater ausgewählt, somit wird die
aggregierte Q3-Statistik nur Rater-spezifisch berechnet.
Das Objekt rater.q3
beinhaltet eine Zeile pro Rater x Item Kombination.
Kombinationen ergeben sich nur für einen Rater, nicht zwischen unterschiedlichen
Ratern.
Anschließend kann man mit aggregate()
separat über Rater und
Kombinationen mitteln und diese als Dotplot darstellen (Paket lattice
).
# Q3 Statistik
mfit.q3 <- tam.modelfit(mod)
rater.pairs <- mfit.q3$stat.itempair
# Nur Paare gleicher Rater wählen
unique.rater <- which(substr(rater.pairs$item1, 4,12) ==
substr(rater.pairs$item2, 4,12))
rater.q3 <- rater.pairs[unique.rater, ]
# Spalten einfügen: Rater, Kombinationen
rater.q3$rater <- substr(rater.q3$item1, 4, 12)
rater.q3 <- rater.q3[order(rater.q3$rater),]
rater.q3$kombi <- as.factor(paste(substr(rater.q3$item1, 1, 2),
substr(rater.q3$item2, 1, 2), sep="_"))
# Statistiken aggregieren: Rater, Kombinationen
dfr.raterQ3 <- aggregate(rater.q3$aQ3, by = list(rater.q3$rater), mean)
colnames(dfr.raterQ3) <- c("Rater", "Q3")
dfr.itemsQ3 <- aggregate(rater.q3$aQ3, by = list(rater.q3$kombi), mean)
colnames(dfr.itemsQ3) <- c("Items", "Q3")
dfr.itemsQ3
Listing 3 (Ergänzung zum Buch): Lattice Dotplot
library(lattice)
library(grid)
# Lattice Dotplot
mean.values <- aggregate(rater.q3$aQ3, list(rater.q3$kombi), mean)[["x"]]
dotplot(aQ3~kombi, data=rater.q3, main="Q3-Statistik", ylab="Q3 (adjustiert)",
col="darkgrey",
panel = function(x,...){
panel.dotplot(x,...)
panel.abline(h = 0, col.line = "grey", lty=3)
grid.points(1:6, mean.values, pch=17)
})
Abschnitt 4: Generalisierbarkeitstheorie
Listing 1: Varianzkomponenten mit lme4 berechnen
Mit der Funktion lmer()
aus dem Paket lme4
schätzen wir die
Varianzkomponenten.
In der Formel definieren wir dabei die Facetten als random effects.
library(lme4)
prodRatL <- datenKapitel07$prodRatL
# Formel definieren
formula1 <- response ~ (1|idstud) + (1|item) + (1|rater) +
(1|rater:item) + (1|idstud:rater) +
(1|idstud:item)
# Modell mit Interaktionen
mod.vk <- lmer(formula1, data=prodRatL)
# Zusammenfassung der Ergebnisse
summary(mod.vk)
Listing 1a (Ergänzung zum Buch): Summary-Funktion für Varianzkomponenten
Wir generieren eine Funktion summary.VarComp()
, die den Output des
Modells mod.vk
in einen ansprechenden data.frame
schreibt.
Hier werden auch die prozentualen Anteile der Varianzkomponenten berechnet.
# Helper-Function um die Varianzkomponenten zu extrahieren
summary.VarComp <- function(mod){
var.c <- VarCorr(mod)
var.c <- c(unlist(var.c) , attr(var.c , "sc")^2)
names(var.c)[length(var.c)] <- "Residual"
dfr1 <- data.frame(var.c)
colnames(dfr1) <- "Varianz"
dfr1 <- rbind(dfr1, colSums(dfr1))
rownames(dfr1)[nrow(dfr1)] <- "Total"
dfr1$prop.Varianz <- 100 * (dfr1$Varianz / dfr1$Varianz[nrow(dfr1)])
dfr1 <- round(dfr1,2)
return(dfr1)
}
summary.VarComp(mod.vk)
Listing 2: Berechnung des G-Koeffizienten
Den G-Koeffizienten berechnen wir nach der Formel im Buch.
vk <- summary.VarComp(mod.vk)
n.p <- length(unique(prodRatL$idstud)) # Anzahl Schüler
n.i <- 4 # Anzahl Items
n.r <- c(1,2,5) # Anzahl Rater
# Varianzkomponenten extrahieren
sig2.p <- vk["idstud", "Varianz"]
sig2.i <- vk["item", "Varianz"]
sig2.r <- vk["rater", "Varianz"]
sig2.ri <- vk["rater:item", "Varianz"]
sig2.pr <- vk["idstud:rater", "Varianz"]
sig2.pi <- vk["idstud:item", "Varianz"]
sig2.pir <- vk["Residual", "Varianz"]
# Fehlervarianz berechnen
sig2.delta <- sig2.pi/n.i + sig2.pr/n.r + sig2.pir/(n.i*n.r)
# G-Koeffizient berechnen
g.koeff <- sig2.p / (sig2.p + sig2.delta)
print(data.frame(n.r, g.koeff), digits = 3)
Listing 2a (Ergänzung zum Buch): Phi-Koeffizient berechnen
sig2.D <- sig2.r/n.r + sig2.i/n.i + sig2.pi/n.i + sig2.pr/n.r +
sig2.ri/(n.i*n.r) + sig2.pir/(n.i*n.r)
phi.koeff <- sig2.p / (sig2.p + sig2.D)
print(data.frame(n.r, phi.koeff), digits = 3)
# Konfidenzintervalle
1.96*sqrt(sig2.D)
Listing 2c (Ergänzung zum Buch): Variable Rateranzahl
Für eine variable Rateranzahl (hier 1 bis 10 Rater) werden die G-Koeffizienten berechnet.
n.i <- 4 # Anzahl Items
dn.r <- seq(1,10) # 1 bis 10 mögliche Rater
delta.i <- sig2.pi/n.i + sig2.pr/dn.r + sig2.pir/(n.i*dn.r)
g.koeff <- sig2.p / (sig2.p + delta.i)
names(g.koeff) <- paste("nR", dn.r, sep="_")
print(g.koeff[1:4])
plot(g.koeff, type = "b", pch = 19, lwd = 2, bty = "n",
main = "G-Koeffizient: Raters",
ylab = "G-Koeffizient",
xlab = "Anzahl Raters", xlim = c(0,10))
abline(v=2, col="darkgrey")
Abschnitt 5: Strukturgleichungsmodelle
In R setzen wir das Struktugleichungsmodell mit dem Paket lavaan
um.
Das Modell wird als Textvariable definiert, welche anschließend der Funktion
sem()
übergeben wird.
Latente Variablen im Messmodell werden in lavaan
mit der Form
latente Variable =~ manifeste
Variable(n)
definiert, die Ladungen werden
dabei auf den Wert 1 fixiert, was mittels der Multiplikation der Variable mit
dem Wert 1 umgesetzt werden kann (z.B. 1*Variable
).
Varianzen und Kovarianzen werden mit Variable ~~ Variable
gebildet,
wobei hier die Multiplikation mit einem Label einerseits den berechneten
Parameter benennt, andererseits, bei mehrmaligem Auftreten des Labels,
Parameterschätzungen von verschiedenen Variablen restringiert bzw. gleichstellt
(z.B. wird für die Within-Varianz von TA
über beide Rater nur ein
Parameter geschätzt, nämlich Vta_R12
).
Die ICC wird für jede Dimension separat direkt im Modell spezifiziert, dies
geschieht durch abgeleitete Variablen mit der Schreibweise
Variable := Berechnung
.
Die Modellspezifikation und der Aufruf der Funktion sem()
ist wie folgt
definiert:
Listing 1 (mit Ergänzung zum Buch): SEM
library(lavaan)
prodPRat <- datenKapitel07$prodPRat
# SEM Modell definieren
lv.mod <- "
# Messmodell
TA =~ 1*TA_R1 + 1*TA_R2
CC =~ 1*CC_R1 + 1*CC_R2
GR =~ 1*GR_R1 + 1*GR_R2
VO =~ 1*VO_R1 + 1*VO_R2
# Varianz Between (Personen)
TA ~~ Vta * TA
CC ~~ Vcc * CC
GR ~~ Vgr * GR
VO ~~ Vvo * VO
# Varianz Within (Rater X Personen)
TA_R1 ~~ Vta_R12 * TA_R1
TA_R2 ~~ Vta_R12 * TA_R2
CC_R1 ~~ Vcc_R12 * CC_R1
CC_R2 ~~ Vcc_R12 * CC_R2
GR_R1 ~~ Vgr_R12 * GR_R1
GR_R2 ~~ Vgr_R12 * GR_R2
VO_R1 ~~ Vvo_R12 * VO_R1
VO_R2 ~~ Vvo_R12 * VO_R2
# Kovarianz Within
TA_R1 ~~ Kta_cc * CC_R1
TA_R2 ~~ Kta_cc * CC_R2
TA_R1 ~~ Kta_gr * GR_R1
TA_R2 ~~ Kta_gr * GR_R2
TA_R1 ~~ Kta_vo * VO_R1
TA_R2 ~~ Kta_vo * VO_R2
CC_R1 ~~ Kcc_gr * GR_R1
CC_R2 ~~ Kcc_gr * GR_R2
CC_R1 ~~ Kcc_vo * VO_R1
CC_R2 ~~ Kcc_vo * VO_R2
GR_R1 ~~ Kgr_vo * VO_R1
GR_R2 ~~ Kgr_vo * VO_R2
# ICC berechnen
icc_ta := Vta / (Vta + Vta_R12)
icc_cc := Vcc / (Vcc + Vcc_R12)
icc_gr := Vgr / (Vgr + Vgr_R12)
icc_vo := Vvo / (Vvo + Vvo_R12)
"
# Schätzung des Modells
mod1 <- sem(lv.mod, data = prodPRat)
summary(mod1, standardized = TRUE)
# Inspektion der Ergebnisse
show(mod1)
fitted(mod1)
inspect(mod1,"cov.lv")
inspect(mod1, "free")
Listing 2: Kompakte Darstellung der Ergebnisse
parameterEstimates(mod1, ci = FALSE,
standardized = TRUE)
Listing 2a (Ergänzung zum Buch): Schreibe Ergebnisse in Latex-Tabelle
library(xtable)
xtable(parameterEstimates(mod1, ci = FALSE,
standardized = TRUE), digits = 3)
Abschnitt 7: Übungen
Übung 1: MFRM M3 und M4 umsetzen und Vergleichen
Wir setzen die Modelle separat in TAM um und lassen uns mit summary()
die Ergebnisse anzeigen.
Einen direkten Zugriff auf die geschätzen Parameter bekommt man mit
mod$xsi.facets
.
Dabei sieht man, dass im Modell 4 keine generalized items gebildet werden, da
hier kein Interaktionsterm vorkommt.
Den Modellvergleich machen wir mit IRT.compareModels(mod3, mod4)
.
Modell 3 weist hier kleinere AIC-Werte auf und scheint etwas besser auf die
Daten zu passen als Modell 4.
Dies zeigt auch der Likelihood-Ratio Test, demnach sich durch das Hinzufügen von
Parametern die Modellpassung verbessert.
library(TAM)
prodRatEx <- datenKapitel07$prodRatEx
# Rater-Facette definieren
facets <- prodRatEx[, "rater", drop = FALSE]
# Response Daten definieren
vars <- c("TA", "CC", "GR", "VO")
resp <- prodRatEx[, vars]
# Personen-ID definieren
pid <- prodRatEx$idstud
# Modell 3
f3 <- ~item * step + rater
mod3 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f3,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
# Modell 4
f4 <- ~item + step + rater
mod4 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f4,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
summary(mod3, file = "TAM_MFRM")
summary(mod4, file = "TAM_MFRM")
mod3$xsi.facets
mod4$xsi.facets
IRT.compareModels(mod3, mod4)
$IC
Model loglike Deviance Npars Nobs AIC BIC AIC3 AICc CAIC
1 mod3 -60795.35 121590.7 69 9748 121728.7 122224.5 121797.7 121729.7 122293.5
2 mod4 -61041.47 122082.9 51 9748 122184.9 122551.4 122235.9 122185.5 122602.4
$LRtest
Model1 Model2 Chi2 df p
1 mod4 mod3 492.2264 18 0
Übung 2: Varianzkomponentenmodell
Das Varianzkomponentenmodell setzen wir für die short prompts nach den Vorgaben
im Buchkapitel um.
Dabei verändern wir die Anzahl der möglichen Rater durch
n.r <- c(2,10,15)
.
Der Phi-Koeffizient kann laut Gleichung 6.9 und 6.10 berechnet werden.
Die Ergebnisse zeigen einen prozentuellen Anteil der Interaktion Person und
Rater von ca. 15%, dieser scheint auf Halo-Effekte hinzuweisen.
library(lme4)
prodRatLEx <- datenKapitel07$prodRatLEx
# Formel definieren
formula1 <- response ~ (1|idstud) + (1|item) + (1|rater) +
(1|rater:item) + (1|idstud:rater) +
(1|idstud:item)
# Modell mit Interaktionen
mod.vk <- lmer(formula1, data=prodRatLEx)
# Zusammenfassung der Ergebnisse
summary(mod.vk)
print(vk <- summary.VarComp(mod.vk))
Varianz prop.Varianz
idstud:item 0.10 2.45
idstud:rater 0.64 15.21
idstud 2.88 67.94
rater:item 0.01 0.22
rater 0.19 4.39
item 0.00 0.02
Residual 0.41 9.78
Total 4.24 100.00
# Verändern der Rateranzahl
n.p <- length(unique(prodRatLEx$idstud)) # Anzahl Schüler
n.i <- 4 # Anzahl Items
n.r <- c(2,10,15) # Anzahl Rater
# Varianzkomponenten extrahieren
sig2.p <- vk["idstud", "Varianz"]
sig2.i <- vk["item", "Varianz"]
sig2.r <- vk["rater", "Varianz"]
sig2.ri <- vk["rater:item", "Varianz"]
sig2.pr <- vk["idstud:rater", "Varianz"]
sig2.pi <- vk["idstud:item", "Varianz"]
sig2.pir <- vk["Residual", "Varianz"]
# Phi-Koeffizient berechnen
sig2.D <- sig2.r/n.r + sig2.i/n.i + sig2.pi/n.i + sig2.pr/n.r +
sig2.ri/(n.i*n.r) + sig2.pir/(n.i*n.r)
phi.koeff <- sig2.p / (sig2.p + sig2.D)
print(data.frame(n.r, phi.koeff), digits = 3)
# Konfidenzintervalle
1.96*sqrt(sig2.D)
Author(s)
Roman Freunberger, Alexander Robitzsch, Claudia Luger-Bazinger
References
Freunberger, R., Robitzsch, A. & Luger-Bazinger, C. (2016). Statistische Analysen produktiver Kompetenzen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 225–258). Wien: facultas.
See Also
Zu datenKapitel07
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 6
, Skalierung und Linking.
Zu Kapitel 8
, Fehlende Daten und Plausible Values.
Zur Übersicht
.
Zur Hilfeseite von TAM
Examples
## Not run:
library(irr)
library(TAM)
library(WrightMap)
library(lattice)
library(grid)
library(lme4)
library(lavaan)
library(xtable)
summary.VarComp <- function(mod){
var.c <- VarCorr(mod)
var.c <- c(unlist(var.c) , attr(var.c , "sc")^2)
names(var.c)[length(var.c)] <- "Residual"
dfr1 <- data.frame(var.c)
colnames(dfr1) <- "Varianz"
dfr1 <- rbind(dfr1, colSums(dfr1))
rownames(dfr1)[nrow(dfr1)] <- "Total"
dfr1$prop.Varianz <- 100 * (dfr1$Varianz / dfr1$Varianz[nrow(dfr1)])
dfr1 <- round(dfr1,2)
return(dfr1)
}
data(datenKapitel07)
prodRat <- datenKapitel07$prodRat
prodRatL <- datenKapitel07$prodRatL
prodPRat <- datenKapitel07$prodPRat
## -------------------------------------------------------------
## Abschnitt 7.2: Beurteilerübereinstimmung
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 7.2, Listing 1: Berechnen der Häufigkeitstabellen
#
# Items auswählen
items <- c("TA", "CC", "GR", "VO")
# Tabelle erzeugen
tab <- apply(prodRat[, items], 2,
FUN=function(x){
prop.table(table(x))*100})
print(tab, digits = 2)
# Mittelwert der Ratings berechnen
round(apply(prodRat[, items], 2, mean), 2)
# -------------------------------------------------------------
# Abschnitt 7.2, Listing 2: Beurteilerübereinstimmung berechnen
#
items <- c("TA", "CC", "GR", "VO")
dfr <- data.frame(items, agree = NA,
kappa = NA, wkappa = NA, korr = NA)
for(i in 1:length(items)){
dat.i <- prodPRat[, grep(items[i], colnames(prodPRat))]
dfr[i, "agree"] <- agree(dat.i, tolerance = 1)["value"]
dfr[i, "kappa"] <- kappa2(dat.i)["value"]
dfr[i, "wkappa"] <- kappa2(dat.i, weight = "squared")["value"]
dfr[i, "korr"] <- cor(dat.i[,1], dat.i[,2])
dfr[i, "icc"] <- icc(dat.i, model = "twoway")["value"]
}
print(dfr, digits = 3)
## -------------------------------------------------------------
## Abschnitt 7.3: Skalierungsmodelle
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 1: Skalierungsmodell mit TAM
#
set.seed(1234)
# Rater-Facette definieren
facets <- prodRat[, "rater", drop = FALSE]
# Response Daten definieren
vars <- c("TA", "CC", "GR", "VO")
resp <- prodRat[, vars]
# Personen-ID definieren
pid <- prodRat$idstud
# Formel für Modell
formulaA <- ~item*step+item*rater
# Modell berechnen
mod <- tam.mml.mfr(resp = resp, facets = facets, formulaA = formulaA,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
summary(mod, file="TAM_MFRM")
# Personenparameter und Rohscores
persons.mod <- tam.wle(mod)
persons.mod$raw.score <- persons.mod$PersonScores / (persons.mod$N.items)
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 1b: Ergänzung zum Buch
# Modellvergleich aller besprochenen Modelle
#
f1 <- ~item * rater * step
mod1 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f1,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f2 <- ~item*step+item*rater
mod2 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f2,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f3 <- ~item * step + rater
mod3 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f3,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
f4 <- ~item + step + rater
mod4 <- tam.mml.mfr(resp = resp, facets = facets, formulaA = f4,
pid = pid, control=list(xsi.start0 = 1,
fac.oldxsi = 0.1,
increment.factor = 1.05))
mod4$xsi.facets
IRT.compareModels(mod1, mod2, mod3, mod4)
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 1c: Ergänzung zum Buch
# Wright-Map: Items und Rater
#
item.labs <- vars
rater.labs <- unique(prodRat$rater)
item.labs <- c(item.labs, rep(NA, length(rater.labs) -
length(item.labs)))
pars <- mod$xsi.facets$xsi
facet <- mod$xsi.facets$facet
item.par <- pars[facet == "item"]
rater.par <- pars[facet == "rater"]
item_rat <- pars[facet == "item:rater"]
len <- length(item_rat)
item.long <- c(item.par, rep(NA, len - length(item.par)))
rater.long <- c(rater.par, rep(NA, len - length(rater.par)))
wrightMap(persons.mod$theta, rbind(item.long, rater.long),
label.items = c("Items", "Rater"),
thr.lab.text = rbind(item.labs, rater.labs),
axis.items = "", min.l=-3, max.l=3,
axis.persons = "Personen")
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 2: Fit-Indices berechnen
#
# Infit/Outfit berechnen
pseudo_items <- colnames(mod$resp)
pss <- strsplit(pseudo_items , split="-")
item_parm <- unlist(lapply(pss, FUN = function(ll){ll[1]}))
rater_parm <- unlist(lapply(pss, FUN = function(ll){ll[2]}))
# Fit Items
res.items <- msq.itemfitWLE(mod, item_parm)
summary(res.items)
# Fit Rater
res.rater <- msq.itemfitWLE(mod, rater_parm)
summary(res.rater)
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 2a: Ergänzung zum Buch
# Abbildung: Histogramm, Rohscores
#
dev.off()
par(mfcol=c(1,2))
hist(persons.mod$theta, col="grey", breaks=40,
main = "",
xlab = "Theta (logits)",
ylab = "Häufigkeit")
with(persons.mod, scatter.smooth(raw.score, theta,
pch = 1, cex = .6, xlab = "Rohscores",
ylab = "Theta (logits)",
lpars = list(col = "darkgrey", lwd = 2,
lty = 1)))
# Abbildung: Fit-Statistik
par(mfcol=c(1,2))
fitdat <- res.rater$fit_data
fitdat$var <- factor(substr(fitdat$item, 1, 2))
boxplot(Outfit~var, data=fitdat,
ylim=c(0,2), main="Outfit")
boxplot(Infit~var, data=fitdat,
ylim=c(0,2), main="Infit")
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 2b: Ergänzung zum Buch
# Korrelationen
#
korr <- c(with(persons.mod, cor(raw.score, theta,
method = "pearson")),
with(persons.mod, cor(raw.score, theta,
method = "spearman")))
print(korr)
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 3: Q3-Statistik berechnen
#
# Q3 Statistik
mfit.q3 <- tam.modelfit(mod)
rater.pairs <- mfit.q3$stat.itempair
# Nur Paare gleicher Rater wählen
unique.rater <- which(substr(rater.pairs$item1, 4,12) ==
substr(rater.pairs$item2, 4,12))
rater.q3 <- rater.pairs[unique.rater, ]
# Spalten einfügen: Rater, Kombinationen
rater.q3$rater <- substr(rater.q3$item1, 4, 12)
rater.q3 <- rater.q3[order(rater.q3$rater),]
rater.q3$kombi <- as.factor(paste(substr(rater.q3$item1, 1, 2),
substr(rater.q3$item2, 1, 2), sep="_"))
# Statistiken aggregieren: Rater, Kombinationen
dfr.raterQ3 <- aggregate(rater.q3$aQ3, by = list(rater.q3$rater), mean)
colnames(dfr.raterQ3) <- c("Rater", "Q3")
dfr.itemsQ3 <- aggregate(rater.q3$aQ3, by = list(rater.q3$kombi), mean)
colnames(dfr.itemsQ3) <- c("Items", "Q3")
dfr.itemsQ3
# -------------------------------------------------------------
# Abschnitt 7.3, Listing 3a: Ergänzung zum Buch
# Lattice Dotplot
#
# Lattice Dotplot
mean.values <- aggregate(rater.q3$aQ3, list(rater.q3$kombi), mean)[["x"]]
dotplot(aQ3~kombi, data=rater.q3, main="Q3-Statistik", ylab="Q3 (adjustiert)",
col="darkgrey",
panel = function(x,...){
panel.dotplot(x,...)
panel.abline(h = 0, col.line = "grey", lty=3)
grid.points(1:6, mean.values, pch=17)
})
## -------------------------------------------------------------
## Abschnitt 7.4: Generalisierbarkeitstheorie
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 7.4, Listing 1: Varianzkomponenten mit lme4 berechnen
#
# Formel definieren
formula1 <- response ~ (1|idstud) + (1|item) + (1|rater) +
(1|rater:item) + (1|idstud:rater) +
(1|idstud:item)
# Modell mit Interaktionen
mod.vk <- lmer(formula1, data=prodRatL)
# Zusammenfassung der Ergebnisse
summary(mod.vk)
# -------------------------------------------------------------
# Abschnitt 7.4, Listing 1a: Ergänzung zum Buch
# Helper-Function um die Varianzkomponenten zu extrahieren
#
summary.VarComp <- function(mod){
var.c <- VarCorr(mod)
var.c <- c(unlist(var.c) , attr(var.c , "sc")^2)
names(var.c)[length(var.c)] <- "Residual"
dfr1 <- data.frame(var.c)
colnames(dfr1) <- "Varianz"
dfr1 <- rbind(dfr1, colSums(dfr1))
rownames(dfr1)[nrow(dfr1)] <- "Total"
dfr1$prop.Varianz <- 100 * (dfr1$Varianz / dfr1$Varianz[nrow(dfr1)])
dfr1 <- round(dfr1,2)
return(dfr1)
}
summary.VarComp(mod.vk)
# -------------------------------------------------------------
# Abschnitt 7.4, Listing 2: Berechnung des G-Koeffizienten
#
vk <- summary.VarComp(mod.vk)
n.p <- length(unique(prodRatL$idstud)) # Anzahl Schüler
n.i <- 4 # Anzahl Items
n.r <- c(1,2,5) # Anzahl Rater
# Varianzkomponenten extrahieren
sig2.p <- vk["idstud", "Varianz"]
sig2.i <- vk["item", "Varianz"]
sig2.r <- vk["rater", "Varianz"]
sig2.ri <- vk["rater:item", "Varianz"]
sig2.pr <- vk["idstud:rater", "Varianz"]
sig2.pi <- vk["idstud:item", "Varianz"]
sig2.pir <- vk["Residual", "Varianz"]
# Fehlervarianz berechnen
sig2.delta <- sig2.pi/n.i + sig2.pr/n.r + sig2.pir/(n.i*n.r)
# G-Koeffizient berechnen
g.koeff <- sig2.p / (sig2.p + sig2.delta)
print(data.frame(n.r, g.koeff), digits = 3)
# -------------------------------------------------------------
# Abschnitt 7.4, Listing 2a: Ergänzung zum Buch
# Phi-Koeffizient berechnen
#
sig2.D <- sig2.r/n.r + sig2.i/n.i + sig2.pi/n.i + sig2.pr/n.r +
sig2.ri/(n.i*n.r) + sig2.pir/(n.i*n.r)
phi.koeff <- sig2.p / (sig2.p + sig2.D)
print(data.frame(n.r, phi.koeff), digits = 3)
# Konfidenzintervalle
1.96*sqrt(sig2.D)
# -------------------------------------------------------------
# Abschnitt 7.4, Listing 2c: Ergänzung zum Buch
# Variable Rateranzahl
#
dev.off()
n.i <- 4 # Anzahl Items
dn.r <- seq(1,10)# 1 bis 10 mögliche Rater
delta.i <- sig2.pi/n.i + sig2.pr/dn.r + sig2.pir/(n.i*dn.r)
g.koeff <- sig2.p / (sig2.p + delta.i)
names(g.koeff) <- paste("nR", dn.r, sep="_")
print(g.koeff[1:4])
# Abbildung variable Rateranzahl
plot(g.koeff, type = "b", pch = 19, lwd = 2, bty = "n",
main = "G-Koeffizient: Raters",
ylab = "G-Koeffizient",
xlab = "Anzahl Raters", xlim = c(0,10))
abline(v=2, col="darkgrey")
## -------------------------------------------------------------
## Abschnitt 7.5: Strukturgleichungsmodelle
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 7.5, Listing 1: SEM
#
# SEM Modell definieren
lv.mod <- "
# Messmodell
TA =~ 1*TA_R1 + 1*TA_R2
CC =~ 1*CC_R1 + 1*CC_R2
GR =~ 1*GR_R1 + 1*GR_R2
VO =~ 1*VO_R1 + 1*VO_R2
# Varianz Personen
TA ~~ Vta * TA
CC ~~ Vcc * CC
GR ~~ Vgr * GR
VO ~~ Vvo * VO
# Varianz Rater X Personen
TA_R1 ~~ Vta_R12 * TA_R1
TA_R2 ~~ Vta_R12 * TA_R2
CC_R1 ~~ Vcc_R12 * CC_R1
CC_R2 ~~ Vcc_R12 * CC_R2
GR_R1 ~~ Vgr_R12 * GR_R1
GR_R2 ~~ Vgr_R12 * GR_R2
VO_R1 ~~ Vvo_R12 * VO_R1
VO_R2 ~~ Vvo_R12 * VO_R2
# Kovarianz
TA_R1 ~~ Kta_cc * CC_R1
TA_R2 ~~ Kta_cc * CC_R2
TA_R1 ~~ Kta_gr * GR_R1
TA_R2 ~~ Kta_gr * GR_R2
TA_R1 ~~ Kta_vo * VO_R1
TA_R2 ~~ Kta_vo * VO_R2
CC_R1 ~~ Kcc_gr * GR_R1
CC_R2 ~~ Kcc_gr * GR_R2
CC_R1 ~~ Kcc_vo * VO_R1
CC_R2 ~~ Kcc_vo * VO_R2
GR_R1 ~~ Kgr_vo * VO_R1
GR_R2 ~~ Kgr_vo * VO_R2
# ICC berechnen
icc_ta := Vta / (Vta + Vta_R12)
icc_cc := Vcc / (Vcc + Vcc_R12)
icc_gr := Vgr / (Vgr + Vgr_R12)
icc_vo := Vvo / (Vvo + Vvo_R12)
"
# Schätzung des Modells
mod1 <- sem(lv.mod, data = prodPRat)
summary(mod1, standardized = TRUE)
# Inspektion der Ergebnisse
show(mod1)
fitted(mod1)
inspect(mod1,"cov.lv")
inspect(mod1, "free")
# -------------------------------------------------------------
# Abschnitt 7.5, Listing 2: Kompakte Darstellung der Ergebnisse
#
parameterEstimates(mod1, ci = FALSE,
standardized = TRUE)
# -------------------------------------------------------------
# Abschnitt 7.5, Listing 2a: Ergänzung zum Buch
# Schreibe Ergebnisse in Latex-Tabelle:
#
xtable(parameterEstimates(mod1, ci = FALSE,
standardized = TRUE), digits = 3)
## End(Not run)
Kapitel 8: Fehlende Daten und Plausible Values
Description
Das ist die Nutzerseite zum Kapitel 8, Fehlende Daten und Plausible Values, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Vorbereitungen
Zur Illustration der Konsequenzen fehlender Daten und der Messfehlerbehaftetheit
von Variablen soll zunächst ein Illustrationsdatensatz (data08I
) mit
N=1500 simuliert werden. Dabei sollen zwei Variablen vorliegen: Der
Sozialstatus X
soll teilweise fehlende Werte aufweisen und die zu
erfassende Kompetenz liegt sowohl als wahrer Wert \theta
als auch als
messfehlerbehaftete Variable \hat{\theta}
vor.
Im Datensatz data08I
liegt sowohl der vollständig beobachtete
Sozialstatus (x
) als auch derselbe Sozialstatus mit teilweise fehlenden
Variablen (X
) vor.
Neben dem Illustrationsdatensatz werden in diesem Kapitel Datensätze der
österreichischen Bildungsstandards im Fach Englisch verwendet.
Der Datensatz data08H
enthält Kovariaten (d.h. Variablen aus Fragebögen
oder administrative Daten) auf Ebene der Schüler (Ebene 1) und auf Ebene der
Schulen (Ebene 2).
Variablen beider Ebenen können dabei fehlende Werte besitzen.
Im Datensatz data08J
sind fehlende Werte des Datensatzes data08H
durch eine Ersetzung von Werten bereits aufgefüllt.
Außerdem liegen Item Responses der Schüler für den Bereich Hörverstehen
(Listening, L) im Datensatz data08K
vor.
Folgende R-Pakete werden in diesem Kapitel verwendet: mice
,
miceadds
, TAM
, pls
.
library(miceadds)
library(mice)
library(TAM)
library(pls)
Abschnitt 8.1.1: Konsequenzen fehlender Daten und messfehlerbehafteter Variablen
Listing 1: Deskriptive Statistiken des Datensatzes
Mit folgendem R-Code werden deskriptive Statistiken des Datensatzes
data08I
ermittelt, an denen die Bedeutung der geeigneten Behandlung
fehlender Werte und von Messfehlern herausgearbeitet werden soll.
data(datenKapitel08)
dat <- datenKapitel08$data08I[,-1]
#*** Missinganteile
round( colMeans( is.na(dat), na.rm=TRUE) , 2 )
#*** Mittelwerte
round( apply( dat , 2 , mean , na.rm=TRUE ) , 2 )
#*** Zusammenhang von Missingindikator und Variablen
round( miceadds::mi_dstat( dat[,c("WLE","X")] ) , 2 )
#*** Varianzen
round( apply( dat , 2 , var , na.rm=TRUE ) , 2 )
#*** Korrelationsmatrix
round( cor( dat , use = "pairwise.complete.obs") , 2 )
Abschnitt 8.2.5: Durchführung der multiplen Imputation in R
Listing 2: Variablenauswahl und leere Imputation
In diesem Abschnitt wird die multiple Imputation basierend auf dem MICE-Ansatz im
Paket mice
in R umgesetzt. Als Datensatz soll data08H
verwendet
werden.
Zur Vereinfachung der Darstellung wählen wir auf der Ebene der Schüler die
Variablen Sozialstatus (HISEI
), Anzahl der Bücher zu Hause (buch
)
und den WLE der Hörverstehenskompetenz (E8LWLE
) sowie einen auf der
Schulebene erfassten Sozialstatus (SES_Schule
) aus.
set.seed(56)
dat <- datenKapitel08$data08H
# wähle Variablen aus
dat1 <- dat[ , c("idschool", "HISEI", "buch", "E8LWLE",
"SES_Schule") ]
colMeans(is.na(dat1))
# führe leere Imputation durch
imp0 <- mice::mice(dat1, m=0, maxit=0)
Listing 3: Spezifikation der Imputationsmethoden
Die nachfolgende Syntax zeigt die Spezifikation der Imputationsmethoden im
Vektor impMethod
in mice
für unser Datenbeispiel.
impMethod <- imp0$method
impMethod["HISEI"] <- "2l.continuous"
# [...] weitere Spezifikationen
impMethod["SES_Schule"] <- "2lonly.norm"
impMethod
Listing 4: Definition der Prädiktormatrix für die Imputation in mice
Nachfolgender R-Code zeigt die Definition der Prädiktormatrix (Matrix
predMatrix
) für die Imputation in mice
.
predMatrix <- imp0$predictorMatrix
predMatrix[-1,"idschool"] <- -2
# [...]
predMatrix
Listing 5: Datenimputation
Die Imputation kann nun unter dem Aufruf der Funktion mice
unter
Übergabe der Imputationsmethoden und der Prädiktormatrix erfolgen.
Für das PMM werden 5 Donoren gewählt. Insgesamt sollen 10 imputierte Datensätze
generiert werden, wobei der Algorithmus 7 Iterationen durchlaufen soll.
imp1 <- mice::mice( dat1, imputationMethod=impMethod,
predictorMatrix=predMatrix, donors=5,
m=10, maxit=7 )
Abschnitt 8.3.2: Dimensionsreduzierende Verfahren für Kovariaten im latenten Regressionsmodell
Listing 6: Kovariatenauswahl, Interaktionsbildung und Bestimmung PLS-Faktoren
Die Methode des Partial Least Squares soll für den Datensatz data08J
illustriert werden.
Es wird zum Auffüllen der Kovariaten mit fehlenden Werten nur ein imputierter
Datensatz erstellt.
Danach wird eine PLS-Regression des WLE der Hörverstehenskompetenz
E8LWLE
auf Kovariaten und deren Interaktionen bestimmt.
Für die Bestimmung der PLS-Faktoren wird das R-Paket pls
verwendet.
Die nachfolgende R-Syntax zeigt die Kovariatenauswahl, die Bildung der
Interaktionen und die Bestimmung der PLS-Faktoren. Insgesamt entstehen durch
Aufnahme der Haupteffekte und Interaktionen 55 Kovariaten.
dat <- datenKapitel08$data08J
#*** Kovariatenauswahl
kovariaten <- scan(what="character", nlines=2)
female migrant HISEI eltausb buch
SK LF NSchueler NKlassen SES_Schule
X <- scale( dat[, kovariaten ] )
V <- ncol(X)
# bilde alle Zweifachinteraktionen
c2 <- combinat::combn(V,2)
X2 <- apply( c2 , 2 , FUN = function(cc){
X[,cc[1]] * X[,cc[2]] } )
X0 <- cbind( X , X2 )
mod1 <- pls::plsr( dat$E8LWLE ~ X0 , ncomp=55 )
summary(mod1)
Abschnitt 8.3.3: Ziehung von Plausible Values in R
In diesem Abschnitt soll die Ziehung von Plausible Values mit dem R-Paket
TAM
illustriert werden. Dabei beschränken wir uns auf den
Kompetenzbereich des Hörverstehens.
Listing 7: PLS-Faktoren auswählen
In Abschnitt 8.3.2 wurden dabei die Kovariaten auf PLS-Faktoren reduziert. Für die Ziehung von Plausible Values werden nachfolgend 10 PLS-Faktoren verwendet.
facs <- mod1$scores[,1:10]
Listing 8: Rasch-Skalierung
Für die Hörverstehenskompetenz im Datensatz data08K
wird nachfolgend das
Messmodell als Rasch-Modell geschätzt. Dabei werden Stichprobengewichte für die
Bestimmung der Itemparameter verwendet.
dat2 <- datenKapitel08$data08K
items <- grep("E8L", colnames(dat2), value=TRUE)
# Schätzung des Rasch-Modells in TAM
mod11 <- TAM::tam.mml( resp= dat2[,items ] ,
pid = dat2$idstud,
pweights = dat2$wgtstud )
Listing 9: Individuelle Likelihood, latente Regressionsmodell und PV-Ziehung
Bei einer Fixierung von Itemparametern ist die bedingte Verteilung
P(\mathbf{X}|\boldsymbol{\theta})
des Messmodells konstant.
Die Schätzung von Item-Response-Modellen erfolgt in TAM
unter Verwendung
eines diskreten Gitters von \boldsymbol{\theta}
-Werten.
Während der Anpassung des Rasch-Modells in mod11
liegt daher die auf
diesem Gitter ausgewertete sog. individuelle Likelihood
P(\mathbf{X}|\boldsymbol{\theta})
vor, die mit der Funktion
IRT.likelihood
aus dem Objekt mod11
extrahiert werden kann.
Das latente Regressionsmodell kann unter Rückgriff auf die individuelle
Likelihood mit der Funktion tam.latreg
angepasst werden.
Die Ziehung der Plausible Values erfolgt anschließend mit der Funktion
tam.pv
.
#*** extrahiere individuelle Likelihood
lmod11 <- IRT.likelihood(mod11)
#*** schätze latentes Regressionsmodell
mod12 <- TAM::tam.latreg( like = lmod11 , Y = facs )
#*** ziehe Plausible Values
pv12 <- TAM::tam.pv(mod12, normal.approx=TRUE,
samp.regr=TRUE , ntheta=400)
Listing 10: Plausible Values extrahieren
Die imputierten Plausible Values lassen sich im Element $pv
des
Ergebnisobjekts aus tam.pv
extrahieren.
#*** Plausible Values für drei verschiedene Schüler
round( pv12$pv[c(2,5,9),] , 3 )
Author(s)
Alexander Robitzsch, Giang Pham, Takuya Yanagida
References
Robitzsch, A., Pham, G. & Yanagida, T. (2016). Fehlende Daten und Plausible Values. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 259–293). Wien: facultas.
See Also
Zu datenKapitel08
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 7
, Statistische Analysen produktiver
Kompetenzen .
Zu Kapitel 9
, Fairer Vergleich in der Rückmeldung.
Zur Übersicht
.
Examples
## Not run:
library(TAM)
library(mice)
library(miceadds)
library(pls)
library(combinat)
library(mitml)
data(datenKapitel08)
data08H <- datenKapitel08$data08H
data08I <- datenKapitel08$data08I
data08J <- datenKapitel08$data08J
data08K <- datenKapitel08$data08K
## -------------------------------------------------------------
## Abschnitt 8.1.1: Konsequenzen fehlender Daten und
## messfehlerbehafteter Variablen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 8.1.1, Listing 1: Deskriptive Statistiken des
# Illustrationsdatensatzes
#
data(datenKapitel08)
dat <- datenKapitel08$data08I[,-1]
#*** Missinganteile
round( colMeans( is.na(dat), na.rm=TRUE) , 2 )
#*** Mittelwerte
round( apply( dat , 2 , mean , na.rm=TRUE ) , 2 )
#*** Zusammenhang von Missingindikator und Variablen
round( miceadds::mi_dstat( dat[,c("WLE","X")] ) , 2 )
#*** Varianzen
round( apply( dat , 2 , var , na.rm=TRUE ) , 2 )
#*** Korrelationsmatrix
round( cor( dat , use = "pairwise.complete.obs") , 2 )
## -------------------------------------------------------------
## Abschnitt 8.2: Multiple Imputation
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 1: Variablenauswahl und leere
# Imputation
#
set.seed(56)
data(datenKapitel08)
dat <- datenKapitel08$data08H
# wähle Variablen aus
dat1 <- dat[ , c("idschool", "HISEI", "buch", "E8LWLE",
"SES_Schule") ]
colMeans(is.na(dat1))
# führe leere Imputation durch
imp0 <- mice::mice(dat1, m=0, maxit=0)
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 2: Spezifikation der Imputations-
# methoden
#
impMethod <- imp0$method
impMethod["HISEI"] <- "2l.continuous"
# [...] weitere Spezifikationen
impMethod["SES_Schule"] <- "2lonly.norm"
impMethod
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 2b: Ergänzung zum Buch
#
# [...] weitere Spezifikationen
impMethod["buch"] <- "2l.pmm"
impMethod
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 3: Definition der Prädiktormatrix
# für die Imputation in mice
#
predMatrix <- imp0$predictorMatrix
predMatrix[-1,"idschool"] <- -2
# [...]
predMatrix
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 3b: Ergänzung zum Buch
#
# [...]
predMatrix[2:4,2:4] <- 3*predMatrix[2:4,2:4]
predMatrix
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 4: Führe Imputation durch
#
imp1 <- mice::mice( dat1, imputationMethod=impMethod,
predictorMatrix=predMatrix, donors=5, m=10, maxit=7)
# -------------------------------------------------------------
# Abschnitt 8.2.5, Listing 4b: Ergänzung zum Buch
#
#-- Mittelwert HISEI
wmod1 <- with( imp1 , lm(HISEI ~ 1))
summary( mice::pool( wmod1 ) )
#-- lineare Regression HISEI auf Büchervariable
wmod2 <- with( imp1 , lm(E8LWLE ~ HISEI) )
summary( mice::pool( wmod2 ))
#-- Inferenz Mehrebenenmodelle mit Paket mitml
imp1b <- mitml::mids2mitml.list(imp1)
wmod3 <- with(imp1b, lme4::lmer( HISEI ~ (1|idschool)) )
mitml::testEstimates(wmod3, var.comp=TRUE)
## ------------------------------------------------------------
## Abschnitt 8.3.2: Dimensionsreduzierende Verfahren für
## Kovariaten im latenten Regressionsmodell
## ------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 8.3.2, Listing 1: Kovariatenauswahl, Interaktions-
# bildung und Bestimmung PLS-Faktoren
#
set.seed(56)
data(datenKapitel08)
dat <- datenKapitel08$data08J
#*** Kovariatenauswahl
kovariaten <- scan(what="character", nlines=2)
female migrant HISEI eltausb buch
SK LF NSchueler NKlassen SES_Schule
X <- scale( dat[, kovariaten ] )
V <- ncol(X)
# bilde alle Zweifachinteraktionen
c2 <- combinat::combn(V,2)
X2 <- apply( c2 , 2 , FUN = function(cc){
X[,cc[1]] * X[,cc[2]] } )
X0 <- cbind( X , X2 )
# Partial Least Squares Regression
mod1 <- pls::plsr( dat$E8LWLE ~ X0 , ncomp=55 )
summary(mod1)
# -------------------------------------------------------------
# Abschnitt 8.3.2, Listing 1b: Ergänzung zum Buch
# Abbildung: Aufgeklärter Varianzanteil
#
# Principal Component Regression (Extraktion der Hauptkomponenten)
mod2 <- pls::pcr( dat$E8LWLE ~ X0 , ncomp=55 )
summary(mod2)
#*** extrahierte Varianzen mit PLS-Faktoren und PCA-Faktoren
res <- mod1
R2 <- base::cumsum(res$Xvar) / res$Xtotvar
ncomp <- 55
Y <- dat$E8LWLE
R21 <- base::sapply( 1:ncomp , FUN = function(cc){
1 - stats::var( Y - res$fitted.values[,1,cc] ) / stats::var( Y )
} )
dfr <- data.frame("comp" = 1:ncomp , "PLS" = R21 )
res <- mod2
R2 <- base::cumsum(res$Xvar) / res$Xtotvar
ncomp <- 55
Y <- dat$E8LWLE
R21 <- base::sapply( 1:ncomp , FUN = function(cc){
1 - stats::var( Y - res$fitted.values[,1,cc] ) / stats::var( Y )
} )
dfr$PCA <- R21
plot( dfr$comp , dfr$PLS , type="l" , xlab="Anzahl Faktoren" ,
ylab="Aufgeklärter Varianzanteil" ,
ylim=c(0,.3) )
points( dfr$comp , dfr$PLS , pch=16 )
points( dfr$comp , dfr$PCA , pch=17 )
lines( dfr$comp , dfr$PCA , lty=2 )
legend( 45 , .15 , c("PLS" , "PCA") , pch=c(16,17) , lty=c(1,2))
## ------------------------------------------------------------
## Abschnitt 8.3.3: Ziehung von Plausible Values in R
## ------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 1: PLS-Faktoren auswählen
#
facs <- mod1$scores[,1:10]
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 1b: Ergänzung zum Buch
#
set.seed(98766)
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 2: Anpassung kognitive Daten
#
data(datenKapitel08)
dat2 <- datenKapitel08$data08K
items <- grep("E8L", colnames(dat2), value=TRUE)
# Schätzung des Rasch-Modells in TAM
mod11 <- TAM::tam.mml( resp= dat2[,items ] ,
pid = dat2$idstud, pweights = dat2$wgtstud )
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 3: Individuelle Likelihood, latentes
# Regressionsmodell und PV-Ziehung
#
#*** extrahiere individuelle Likelihood
lmod11 <- IRT.likelihood(mod11)
#*** schätze latentes Regressionsmodell
mod12 <- TAM::tam.latreg( like = lmod11 , Y = facs )
#*** ziehe Plausible Values
pv12 <- TAM::tam.pv(mod12, normal.approx=TRUE,
samp.regr=TRUE , ntheta=400)
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 4: Plausible Values extrahieren
#
#*** Plausible Values für drei verschiedene Schüler
round( pv12$pv[c(2,5,9),] , 3 )
# -------------------------------------------------------------
# Abschnitt 8.3.3, Listing 4b: Ergänzung zum Buch
#
hist( pv12$pv$PV1.Dim1 )
# Korrelation mit Kovariaten
round( cor( pv12$pv$PV1.Dim1 , dat[,kovariaten] ,
use="pairwise.complete.obs") , 3 )
round( cor( dat$E8LWLE , dat[,kovariaten] ,
use="pairwise.complete.obs" ) , 3 )
## End(Not run)
Kapitel 9: Fairer Vergleich in der Rueckmeldung
Description
Das ist die Nutzerseite zum Kapitel 9, Fairer Vergleich in der Rückmeldung, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Vorbereitungen
Der zur Illustration verwendete Datensatz dat
beinhaltet (imputierte)
aggregierte Leistungs- und Hintergrunddaten von 244 Schulen, bestehend aus 74
ländlichen allgemeinbildenden Pflichtschulen (APS, Stratum 1), 69 städtischen
APS (Stratum 2), 52 ländlichen allgemeinbildenden höheren Schulen (AHS, Stratum
3) und 49 städtischen AHS (Stratum 4).
Im Kapitel wird zur Bildung von Interaktionseffekten und quadratischen Termen
der Kovariaten eine neue Funktion covainteraction
verwendet.
data(datenKapitel09)
dat <- datenKapitel09
covainteraction <- function(dat,covas,nchar){
for(ii in 1:(length(covas))){
vv1 <- covas[ii]
# Interaktion von vv1 mit sich selbst
subname1 <- substr(vv1,1,nchar)
intvar <- paste0(subname1, subname1)
if(vv1 == covas[1]){
dat.int <- dat[,vv1]*dat[,vv1];
newvars <- intvar } else {
dat.int <- cbind(dat.int,dat[,vv1]*dat[,vv1]);
newvars <- c(newvars,intvar)
}
# Interaktion von vv1 mit restlichen Variablen
if(ii < length(covas)){
for(jj in ((ii+1):length(covas))){
vv2 <- covas[jj]
subname2 <- substr(vv2,1,nchar)
intvar <- paste0(subname1, subname2)
newvars <- c(newvars, intvar)
dat.int <- cbind(dat.int,dat[,vv1]*dat[,vv2])
}
}
}
dat.int <- data.frame(dat.int)
names(dat.int) <- newvars
return(dat.int)
}
Abschnitt 9.2.5.1: Kovariaten und Interaktionsterme
Listing 1: Kovariatenauswahl und z-Standardisierung
Als Variablen zur Beschreibung von Kontext und Schülerzusammensetzung in den
Schulen werden in diesem Beispiel die logarithmierte Schulgröße groesse
,
der Anteil an Mädchen female
, der Anteil an Schülerinnen und Schülern mit
Migrationshintergrund mig
und der mittlere sozioökonomische Status (SES)
sozstat
eingeführt.
Die abhängige Variable ist die aggregierte
Schülerleistung der Schule TWLE
. Alle Kovariaten (vars
) werden
zunächst z-standardisiert (zvars
).
vars <- c("groesse","female","mig","sozstat")
zvars <- paste0("z",vars)
dat[,zvars] <- scale(dat[,vars],scale = TRUE)
Listing 2: Interaktionen bilden, z-standardisieren
Zur Optimierung der Modellspezifikation werden Interaktionseffekte und
quadratische Terme der Kovariaten gebildet, dann z-standardisiert und in den
Gesamtdatensatz hinzugefügt.
Die neuen Variablennamen sind in der Liste intvars
aufgelistet.
dat1 <- LSAmitR::covainteraction(dat = dat,covas = zvars,nchar = 4)
intvars <- names(dat1) # Interaktionsvariablen
dat1[,intvars] <- scale(dat1[,intvars],scale = TRUE)
dat <- cbind(dat,dat1)
Listing 3: Haupt- und Interaktionseffekte
maineff <- zvars # Haupteffekte
alleff <- c(zvars,intvars) # Haupt- und Interaktionseffekte
Abschnitt 9.2.5.2: OLS-Regression
Listing 4: OLS-Regression mit Haupteffekten
Das OLS-Regressionsmodell mit den Haupteffekten als Modellprädiktoren
(ols.mod1
) für Schulen im Stratum (st
) 4
fm.ols1 <- paste0("TWLE ~ ",paste(maineff,collapse=" + "))
fm.ols1 <- as.formula(fm.ols1) # Modellgleichung
st <- 4
pos <- which(dat$stratum == st) # Schulen im Stratum st
ols.mod1 <- lm(formula = fm.ols1,data = dat[pos,]) # Regression
Abschnitt 9.2.5.3: Lasso-Regression
Listing 5: Datenaufbereitung
Für die Durchführung der Lasso-Regression wird das R-Paket glmnet
(Friedman et al., 2010) eingesetzt. Die Kovariatenmatrix (Z
) sowie der
Vektor der abhängigen Leistungswerte (Y
) müssen definiert werden.
library(glmnet)
Z <- as.matrix(dat[pos,alleff]) # Kovariatenmatrix
Y <- dat$TWLE[pos] # Abhängige Variable
Listing 6: Bestimmung Teilmengen für Kreuzvalidierung, Lasso-Regression
Das Lasso-Verfahren wird mit der Funktion cv.glmnet()
durchgeführt.
Zur Auswahl eines optimalen shrinkage \lambda
wird das Verfahren der
K-fachen Kreuzvalidierung verwendet.
Die Schulstichprobe wird durch ID-Zuweisung (foldid
) verschiedenen
Teilmengen zugewiesen.
nid <- floor(length(pos)/3) # Teilmengen definieren
foldid <- rep(c(1:nid),3,length.out=length(pos)) # Zuweisung
lasso.mod2 <- glmnet::cv.glmnet(x=Z,y=Y,alpha = 1, foldid = foldid)
Listing 7: Erwartungswerte der Schulen
Entsprechend lambda.min
werden die Regressionskoeffizienten und die
entsprechenden Erwartungswerte der Schulen bestimmt.
lasso.pred2 <- predict(lasso.mod2,newx = Z,s="lambda.min")
dat$expTWLE.Lasso2[pos] <- as.vector(lasso.pred2)
Listing 8: Bestimmung R^2
Bestimmung des aufgeklärten Varianzanteils der Schulleistung R^2
.
varY <- var(dat$TWLE[pos])
varY.lasso.mod2 <- var(dat$expTWLE.Lasso2[pos])
R2.lasso.mod2 <- varY.lasso.mod2/varY
Abschnitt 9.2.5.4: Nichtparametrische Regression
Listing 9: Distanzberechnung
Der erste Schritt zur Durchführung einer nichtparametrischen Regression ist die
Erstellung der Distanzmatrix zwischen Schulen. In diesem Beispiel wird die
euklidische Distanz als Distanzmaß berechnet, alle standardisierten Haupteffekte
sind eingeschlossen. Außerdem setzen wir die Gewichte von allen Kovariaten
(gi
) auf 1. dfr.i
in diesem Beispiel ist die Distanzmatrix für
erste Schule im Stratum.
N <- length(pos) # Anzahl Schulen im Stratum
schools <- dat$idschool[pos] # Schulen-ID
i <- 1
# Teildatensatz von Schule i
dat.i <- dat[pos[i],c("idschool","TWLE",maineff)]
names(dat.i) <- paste0(names(dat.i),".i")
# Daten der Vergleichsschulen
dat.vgl <- dat[pos[-i],c("idschool","TWLE",maineff)]
index.vgl <- match(dat.vgl$idschool,schools)
# Daten zusammenfügen
dfr.i <- data.frame("index.i"=i,dat.i,"index.vgl"=index.vgl,
dat.vgl, row.names=NULL)
# Distanz zur Schule i
dfr.i$dist <- 0
gi <- c(1,1,1,1)
for(ii in 1:length(maineff)){
vv <- maineff[ii]
pair.vv <- grep(vv, names(dfr.i), value=T)
dist.vv <- gi[ii]*((dfr.i[,pair.vv[1]]-dfr.i[,pair.vv[2]])^2)
dfr.i$dist <- dfr.i$dist + dist.vv }
Listing 10: H initiieren
p(x) = \frac{\lambda^x e^{-\lambda}}{x!}
.
Die Gewichte w_{ik}
für jedes Paar (i, k) von Schulen werden mithilfe der
Distanz, der Gauß’schen Kernfunktion (dnorm
) als Transformationsfunktion
sowie einer schulspezifischen Bandweite h_i
berechnet. Die Auswahl des optimalen
Werts \hat{h_i}
für jede Schule i erfolgt nach Vieu (1991). Zunächst wird
ein Vektor H
so gewählt, dass der optimale Wert \hat{h_i}
größer
als der kleinste und kleiner als der größte Wert in H
ausfällt.
Je kleiner das Intervall zwischen den Werten in H
ist, desto
wahrscheinlicher ist, dass ein Listenelement den optimalen Wert erlangt.
Auf der anderen Seite korrespondiert die Rechenzeit mit der Länge von H
.
Gemäß der Größe der Vergleichsgruppe wählen wir eine Länge von 30 für H
,
zusätzlich wird ein sehr großer Wert (100000) für die Fälle hinzugefügt, bei
denen alle Gewichte beinahe gleich sind.
d.dist <- max(dfr.i$dist)-min(dfr.i$dist)
H <- c(seq(d.dist/100,d.dist,length=30),100000)
V1 <- length(H)
# Anzahl Vergleichsschulen
n <- nrow(dfr.i)
Listing 11: Leave-One-Out-Schätzer der jeweiligen Vergleichsschule k nach h in H
Auf Basis aller Werte in H
und dem jeweils entsprechenden Gewicht w_{ik}
(wgt.h
) werden die Leave-One-Out-Schätzer der jeweiligen Vergleichsschule
(pred.k
) berechnet.
sumw <- 0*H # Vektor w_{ik} initiieren, h in H
av <- "TWLE"
dfr0.i <- dfr.i[,c("idschool",av)]
# Schleife über alle h-Werte
for (ll in 1:V1 ){
h <- H[ll]
# Gewicht w_{ik} bei h
dfr.i$wgt.h <- dnorm(sqrt(dfr.i$dist), mean=0, sd=sqrt(h))
# Summe von w_{ik} bei h
sumw[which(H==h)] <- sum(dfr.i$wgt.h)
# Leave-one-out-Schätzer von Y_k
for (k in 1:n){
# Regressionsformel
fm <- paste0(av,"~",paste0(maineff,collapse="+"))
fm <- as.formula(fm)
# Regressionsanalyse ohne Beitrag von Schule k
dfr.i0 <- dfr.i[-k,]
mod.k <- lm(formula=fm,data=dfr.i0,weights=dfr.i0$wgt.h)
# Erwartungswert anhand Kovariaten der Schule k berechnen
pred.k <- predict(mod.k, dfr.i)[k]
dfr0.i[k,paste0( "h_",h) ] <- pred.k
}}
# Erwartungswerte auf Basis verschiedener h-Werte
dfr1 <- data.frame("idschool.i"=dfr.i$idschool.i[1],"h"=H )
Listing 12: Kreuzvalidierungskriterium nach h in H
Zur Berechnung der Kreuzvalidierungskriterien (CVh
, je kleiner, desto
reliabler sind die Schätzwerte) für alle Werte h in H
verwenden wir in
diesem Beispiel die Plug-in-Bandweite nach Altman und Leger (1995) (hAL
),
die mit der Funktion ALbw()
des R-Pakets kerdiest
aufrufbar ist.
library(kerdiest)
hAL <- kerdiest::ALbw("n",dfr.i$dist) # Plug-in Bandweite
dfr.i$cross.h <- hAL
dfr.i$crosswgt <- dnorm( sqrt(dfr.i$dist), mean=0, sd = sqrt(hAL) )
# Kreuzvalidierungskriterium CVh
vh <- grep("h_",colnames(dfr0.i),value=TRUE)
for (ll in 1:V1){
dfr1[ll,"CVh"] <- sum( (dfr0.i[,av] - dfr0.i[,vh[ll]])^2 *
dfr.i$crosswgt) / n}
Listing 13: Bestimmung des optimalen Wertes von h
Der optimale Wert von h in H
(h.min
) entspricht dem mit dem
kleinsten resultierenden CVh
.
dfr1$min.h.index <- 0
ind <- which.min( dfr1$CVh )
dfr1$min.h.index[ind] <- 1
dfr1$h.min <- dfr1$h[ind]
Listing 14: Kleinste Quadratsumme der Schätzfehler
Kleinste Quadratsumme der Schätzfehler der nichtparametrischen Regression mit
h=h.min
.
dfr1$CVhmin <- dfr1[ ind , "CVh" ]
Listing 15: Effizienzsteigerung
Die Effizienz (Steigerung der Schätzungsreliabilität) der nichtparametrischen
Regression gegenüber der linearen Regression (äquivalent zu CVh
bei
h=100000).
dfr1$eff_gain <- 100 * ( dfr1[V1,"CVh"] / dfr1$CVhmin[1] - 1 )
Listing 16: Durchführung der nichtparametrischen Regression
h <- dfr1$h.min[1] # h.min
dfr.i$wgt.h <- dnorm(sqrt(dfr.i$dist),sd=sqrt(h))/
dnorm(0,sd= sqrt(h)) # w_{ik} bei h.min
dfr.i0 <- dfr.i
# Lokale Regression
mod.ii <- lm(formula=fm,data=dfr.i0,weights=dfr.i0$wgt.h)
# Kovariaten Schule i
predM <- data.frame(dfr.i[1,paste0(maineff,".i")])
names(predM) <- maineff
pred.ii <- predict(mod.ii, predM) # Schätzwert Schule i
dat$expTWLE.np[match(dfr1$idschool.i[1],dat$idschool)] <- pred.ii
Abschnitt 9.2.7, Berücksichtigung der Schätzfehler
Der Erwartungsbereich wird nach der im Buch beschriebenen Vorgehensweise bestimmt.
Listing 17: Bestimmung des Erwartungsbereichs
Bestimmung der Breite des Erwartungsbereichs aller Schulen auf Basis der Ergebnisse der OLS-Regression mit Haupteffekten.
vv <- "expTWLE.OLS1" # Variablenname
mm <- "OLS1" # Kurzname des Modells
dfr <- NULL # Ergebnistabelle
# Schleife über alle möglichen Breite von 10 bis 60
for(w in 10:60){
# Variablen für Ergebnisse pro w
var <- paste0(mm,".pos.eb",w) # Position der Schule
var.low <- paste0(mm,".eblow",w) # Untere Grenze des EBs
var.upp <- paste0(mm,".ebupp",w) # Obere Grenze des EBs
# Berechnen
dat[,var.low] <- dat[,vv]-w/2 # Untere Grenze des EBs
dat[,var.upp] <- dat[,vv]+w/2 # Obere Grenze des EBs
# Position: -1=unterhalb, 0=innerhalb, 1=oberhalb des EBs
dat[,var] <- -1*(dat$TWLE < dat[,var.low]) + 1*(dat$TWLE > dat[,var.upp])
# Verteilung der Schulpositionen
tmp <- data.frame(t(matrix(prop.table(table(dat[,var])))))
names(tmp) <- c("unterhalb","innerhalb","oberhalb")
tmp <- data.frame("ModellxBereich"=var,tmp); dfr <- rbind(dfr,tmp) }
# Abweichung zur Wunschverteilung 25-50-25
dfr1 <- dfr
dfr1[,c(2,4)] <- (dfr1[,c(2,4)] - .25)^2
dfr1[,3] <- (dfr1[,3] - .5)^2
dfr1$sumquare <- rowSums(dfr1[,-1])
# Auswahl markieren
dfr$Auswahl <- 1*(dfr1$sumquare == min(dfr1$sumquare) )
Author(s)
Giang Pham, Alexander Robitzsch, Ann Cathrice George, Roman Freunberger
References
Pham, G., Robitzsch, A., George, A. C. & Freunberger, R. (2016). Fairer Vergleich in der Rückmeldung. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 295–332). Wien: facultas.
See Also
Zu datenKapitel09
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 8
, Fehlende Daten und Plausible Values.
Zu Kapitel 10
, Reporting und Analysen.
Zur Übersicht
.
Examples
## Not run:
library(miceadds)
library(glmnet)
library(kerdiest)
covainteraction <- function(dat,covas,nchar){
for(ii in 1:(length(covas))){
vv1 <- covas[ii]
# Interaktion von vv1 mit sich selbst
subname1 <- substr(vv1,1,nchar)
intvar <- paste0(subname1, subname1)
if(vv1 == covas[1]){
dat.int <- dat[,vv1]*dat[,vv1];
newvars <- intvar } else {
dat.int <- cbind(dat.int,dat[,vv1]*dat[,vv1]);
newvars <- c(newvars,intvar)
}
# Interaktion von vv1 mit restlichen Variablen
if(ii < length(covas)){
for(jj in ((ii+1):length(covas))){
vv2 <- covas[jj]
subname2 <- substr(vv2,1,nchar)
intvar <- paste0(subname1, subname2)
newvars <- c(newvars, intvar)
dat.int <- cbind(dat.int,dat[,vv1]*dat[,vv2])
}
}
}
dat.int <- data.frame(dat.int)
names(dat.int) <- newvars
return(dat.int)
}
data(datenKapitel09)
dat <- datenKapitel09
# Platzhalter für Leistungsschätzwerte aller Modelle
dat$expTWLE.OLS1 <- NA
dat$expTWLE.OLS2 <- NA
dat$expTWLE.Lasso1 <- NA
dat$expTWLE.Lasso2 <- NA
dat$expTWLE.np <- NA
## -------------------------------------------------------------
## Abschnitt 9.2.5, Umsetzung in R
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 9.2.5.1, Listing 1: Kovariatenauswahl und
# z-Standardisierung
#
vars <- c("groesse","female","mig","sozstat")
zvars <- paste0("z",vars)
dat[,zvars] <- scale(dat[,vars],scale = TRUE)
# -------------------------------------------------------------
# Abschnitt 9.2.5.1, Listing 2:
#
# Interaktionen bilden, z-standardisieren
dat1 <- LSAmitR::covainteraction(dat = dat,covas = zvars,nchar = 4)
intvars <- names(dat1) # Interaktionsvariablen
dat1[,intvars] <- scale(dat1[,intvars],scale = TRUE)
dat <- cbind(dat,dat1)
# -------------------------------------------------------------
# Abschnitt 9.2.5.1, Listing 3: Modellprädiktoren: Haupt- und
# Interaktionseffekte
#
maineff <- zvars # Haupteffekte
alleff <- c(zvars,intvars) # Haupt- und Interaktionseffekte
# -------------------------------------------------------------
# Abschnitt 9.2.5.2, Listing 4: OLS-Regression mit Haupteffekten
#
fm.ols1 <- paste0("TWLE ~ ",paste(maineff,collapse=" + "))
fm.ols1 <- as.formula(fm.ols1) # Modellgleichung
st <- 4
pos <- which(dat$stratum == st) # Schulen im Stratum st
ols.mod1 <- lm(formula = fm.ols1,data = dat[pos,]) # Regression
# -------------------------------------------------------------
# Abschnitt 9.2.5.3, Listing 5: Lasso-Regression
# Datenaufbereitung
#
library(glmnet)
Z <- as.matrix(dat[pos,alleff]) # Kovariatenmatrix
Y <- dat$TWLE[pos] # Abhängige Variable
# -------------------------------------------------------------
# Abschnitt 9.2.5.3, Listing 6: Lasso-Regression
# Bestimmung Teilmengen für Kreuzvalidierung, Lasso-Regression
#
nid <- floor(length(pos)/3) # Teilmengen definieren
foldid <- rep(c(1:nid),3,length.out=length(pos)) # Zuweisung
lasso.mod2 <- glmnet::cv.glmnet(x=Z,y=Y,alpha = 1, foldid = foldid)
# -------------------------------------------------------------
# Abschnitt 9.2.5.3, Listing 7: Lasso-Regression
# Erwartungswerte der Schulen
#
lasso.pred2 <- predict(lasso.mod2,newx = Z,s="lambda.min")
dat$expTWLE.Lasso2[pos] <- as.vector(lasso.pred2)
# -------------------------------------------------------------
# Abschnitt 9.2.5.3, Listing 8: Lasso-Regression
# Bestimmung R^2
#
varY <- var(dat$TWLE[pos])
varY.lasso.mod2 <- var(dat$expTWLE.Lasso2[pos])
R2.lasso.mod2 <- varY.lasso.mod2/varY
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 9: Nichtparametrische Regression
# Distanzberechnung zur Schule i (Stratum st)
#
N <- length(pos) # Anzahl Schulen im Stratum
schools <- dat$idschool[pos] # Schulen-ID
i <- 1
# Teildatensatz von Schule i
dat.i <- dat[pos[i],c("idschool","TWLE",maineff)]
names(dat.i) <- paste0(names(dat.i),".i")
# Daten der Vergleichsschulen
dat.vgl <- dat[pos[-i],c("idschool","TWLE",maineff)]
index.vgl <- match(dat.vgl$idschool,schools)
# Daten zusammenfügen
dfr.i <- data.frame("index.i"=i,dat.i,"index.vgl"=index.vgl,
dat.vgl, row.names=NULL)
# Distanz zur Schule i
dfr.i$dist <- 0
gi <- c(1,1,1,1)
for(ii in 1:length(maineff)){
vv <- maineff[ii]
pair.vv <- grep(vv, names(dfr.i), value=T)
dist.vv <- gi[ii]*((dfr.i[,pair.vv[1]]-dfr.i[,pair.vv[2]])^2)
dfr.i$dist <- dfr.i$dist + dist.vv }
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 10: Nichtparametrische Regression
#
# H initiieren
d.dist <- max(dfr.i$dist)-min(dfr.i$dist)
H <- c(seq(d.dist/100,d.dist,length=30),100000)
V1 <- length(H)
# Anzahl Vergleichsschulen
n <- nrow(dfr.i)
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 11: Nichtparametrische Regression
# Berechnung der Leave-One-Out-Schätzer der jeweiligen
# Vergleichsschule k nach h in H
#
sumw <- 0*H # Vektor w_{ik} initiieren, h in H
av <- "TWLE"
dfr0.i <- dfr.i[,c("idschool",av)]
# Schleife über alle h-Werte
for (ll in 1:V1 ){
h <- H[ll]
# Gewicht w_{ik} bei h
dfr.i$wgt.h <- dnorm(sqrt(dfr.i$dist), mean=0, sd=sqrt(h))
# Summe von w_{ik} bei h
sumw[which(H==h)] <- sum(dfr.i$wgt.h)
# Leave-one-out-Schätzer von Y_k
for (k in 1:n){
# Regressionsformel
fm <- paste0(av,"~",paste0(maineff,collapse="+"))
fm <- as.formula(fm)
# Regressionsanalyse ohne Beitrag von Schule k
dfr.i0 <- dfr.i[-k,]
mod.k <- lm(formula=fm,data=dfr.i0,weights=dfr.i0$wgt.h)
# Erwartungswert anhand Kovariaten der Schule k berechnen
pred.k <- predict(mod.k, dfr.i)[k]
dfr0.i[k,paste0( "h_",h) ] <- pred.k
}}
# Erwartungswerte auf Basis verschiedener h-Werte
dfr1 <- data.frame("idschool.i"=dfr.i$idschool.i[1],"h"=H )
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 12: Nichtparametrische Regression
# Berechnung des Kreuzvalidierungskriteriums nach h in H
#
library(kerdiest)
hAL <- kerdiest::ALbw("n",dfr.i$dist) # Plug-in Bandweite
dfr.i$cross.h <- hAL
dfr.i$crosswgt <- dnorm( sqrt(dfr.i$dist), mean=0, sd = sqrt(hAL) )
# Kreuzvalidierungskriterium CVh
vh <- grep("h_",colnames(dfr0.i),value=TRUE)
for (ll in 1:V1){
dfr1[ll,"CVh"] <- sum( (dfr0.i[,av] - dfr0.i[,vh[ll]])^2 *
dfr.i$crosswgt) / n}
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 13: Nichtparametrische Regression
# Bestimmung optimales Wertes von h (h.min)
#
dfr1$min.h.index <- 0
ind <- which.min( dfr1$CVh )
dfr1$min.h.index[ind ] <- 1
dfr1$h.min <- dfr1$h[ind]
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 14: Nichtparametrische Regression
# Kleinste Quadratsumme der Schätzfehler
#
dfr1$CVhmin <- dfr1[ ind , "CVh" ]
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 15: Nichtparametrische Regression
# Effizienzsteigerung berechnen
#
dfr1$eff_gain <- 100 * ( dfr1[V1,"CVh"] / dfr1$CVhmin[1] - 1 )
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Listing 16: Nichtparametrische Regression
# Durchführung der nichtparametrischen Regression bei h=h.min
#
h <- dfr1$h.min[1] # h.min
dfr.i$wgt.h <- dnorm(sqrt(dfr.i$dist),sd=sqrt(h))/
dnorm(0,sd= sqrt(h)) # w_{ik} bei h.min
dfr.i0 <- dfr.i
# Lokale Regression
mod.ii <- lm(formula=fm,data=dfr.i0,weights=dfr.i0$wgt.h)
# Kovariaten Schule i
predM <- data.frame(dfr.i[1,paste0(maineff,".i")])
names(predM) <- maineff
pred.ii <- predict(mod.ii, predM) # Schätzwert Schule i
dat[match(dfr1$idschool.i[1],dat$idschool), "expTWLE.np"] <- pred.ii
## -------------------------------------------------------------
## Abschnitt 9.2.5, Umsetzung in R, Ergänzung zum Buch
## -------------------------------------------------------------
# Korrelationen zwischen Haupteffekten
cor(dat[,maineff]) # gesamt
# Pro Stratum
for(s in 1:4) print(cor(dat[which(dat$stratum == s),maineff]))
# -------------------------------------------------------------
# Abschnitt 9.2.5.2, Ergänzung zum Buch
# OLS-Regression
#
# Modellgleichung nur mit Haupteffekten
fm.ols1 <- paste0("TWLE ~ ",paste(maineff,collapse=" + "))
fm.ols1 <- as.formula(fm.ols1)
# Modellgleichung mit Haupteffekten ohne zgroesse
fm.ols1a <- paste0("TWLE ~ ",paste(setdiff(maineff,c("zgroesse")),
collapse=" + "))
fm.ols1a <- as.formula(fm.ols1a)
# Modellgleichung mit Haupt- und Interaktionseffekten
fm.ols2 <- paste0("TWLE ~ ",paste(alleff,collapse=" + "))
fm.ols2 <- as.formula(fm.ols2)
# Ergebnistabelle über 4 Strata hinweg vorbereiten
tab1 <- data.frame("Variable"=c("(Intercept)",maineff))
tab2 <- data.frame("Variable"=c("(Intercept)",alleff))
# Durchführung: Schleife über vier Strata
for(st in 1:4){
# st <- 4
# Position Schulen des Stratums st im Datensatz
pos <- which(dat$stratum == st)
#---------------------------------
# OLS-Modell 1
# Durchführung
ols.mod1 <- lm(formula = fm.ols1,data = dat[pos,])
ols.mod1a <- lm(formula = fm.ols1a,data = dat[pos,])
# Modellergebnisse anzeigen
summary(ols.mod1)
summary(ols.mod1a)
# Erwartungswerte der Schulen
dat$expTWLE.OLS1[pos] <- fitted(ols.mod1)
# Ergebnisse in Tabelle speichern
par <- summary(ols.mod1)
tab.s <- data.frame(par$coef,R2=par$r.squared,R2.adj=par$adj.r.squared)
names(tab.s) <- paste0("stratum",st,
c("_coef","_SE","_t","_p","_R2","_R2.adj"))
tab1 <- cbind(tab1, tab.s)
# Durchführung OLS-Modell 2
ols.mod2 <- lm(formula = fm.ols2,data = dat[pos,])
# Modellergebnisse anzeigen
summary(ols.mod2)
# Erwartungswerte der Schulen
dat$expTWLE.OLS2[pos] <- fitted(ols.mod2)
# Ergebnisse in Tabelle speichern
par <- summary(ols.mod2)
tab.s <- data.frame(par$coef,R2=par$r.squared,R2.adj=par$adj.r.squared)
names(tab.s) <- paste0("stratum",st,
c("_coef","_SE","_t","_p","_R2","_R2.adj"))
tab2 <- cbind(tab2, tab.s)
}
# Daten Schule 1196 ansehen
dat[which(dat$idschool == 1196),]
# Schätzwerte nach ols.mod1 und ols.mod2 vergleichen
summary(abs(dat$expTWLE.OLS1 - dat$expTWLE.OLS2))
cor.test(dat$expTWLE.OLS1,dat$expTWLE.OLS2)
# Grafische Darstellung des Vergleich (Schule 1196 rot markiert)
plot(dat$expTWLE.OLS1,dat$expTWLE.OLS2,xlim=c(380,650),ylim=c(380,650),
col=1*(dat$idschool == 1196)+1,pch=15*(dat$idschool == 1196)+1)
abline(a=0,b=1)
# -------------------------------------------------------------
# Abschnitt 9.2.5.3, Ergänzung zum Buch
# Lasso-Regression
#
library(glmnet)
# Variablen für Erwartungswerte
dat$expTWLE.Lasso2 <- dat$expTWLE.Lasso1 <- NA
# Tabelle für Modellergebnisse
tab3 <- data.frame("Variable"=c("(Intercept)",maineff))
tab4 <- data.frame("Variable"=c("(Intercept)",alleff))
for(st in 1:4){
# st <- 4
# Position Schulen des Stratums st im Datensatz
pos <- which(dat$stratum == st)
#------------------------------------------------------------#
# Lasso-Regression mit den Haupteffekten
# Kovariatenmatrix
Z <- as.matrix(dat[pos,maineff])
# Abhängige Variable
Y <- dat$TWLE[pos]
# Kreuzvalidierung: Teilmengen definieren
nid <- floor(length(pos)/3)
# Schulen zu Teilmengen zuordnen
foldid <- rep(c(1:nid),3,length.out=length(pos))
# Regression
lasso.mod1 <- cv.glmnet(x=Z,y=Y,alpha = 1, foldid = foldid)
# Ergebnisse ansehen
print(lasso.mod1)
# Lasso-Koeffizienten bei lambda.min
print(lasso.beta <- coef(lasso.mod1,s="lambda.min"))
# Erwartungswerte der Schulen
lasso.pred1 <- predict(lasso.mod1,newx = Z,s="lambda.min")
dat$expTWLE.Lasso1[pos] <- as.vector(lasso.pred1)
# R2 bestimmen
varY <- var(dat$TWLE[pos])
varY.lasso.mod1 <- var(dat$expTWLE.Lasso1[pos])
print(R2.lasso.mod1 <- varY.lasso.mod1/varY)
# Ergebnistabelle
vv <- paste0("coef.stratum",st); tab3[,vv] <- NA
tab3[lasso.beta@i+1,vv] <- lasso.beta@x
vv <- paste0("lambda.stratum",st); tab3[,vv] <- lasso.mod1$lambda.min
vv <- paste0("R2.stratum",st); tab3[,vv] <- R2.lasso.mod1
#------------------------------------------------------------#
# Lasso-Regression mit Haupt- und Interaktionseffekten
# Kovariatenmatrix
Z <- as.matrix(dat[pos,alleff])
# Regression
lasso.mod2 <- cv.glmnet(x=Z,y=Y,alpha = 1, foldid = foldid)
# Ergebnisausdruck
print(lasso.mod2)
# Lasso-Koeffizienten bei lambda.min
print(lasso.beta <- coef(lasso.mod2,s="lambda.min"))
# Erwartungswerte der Schulen
lasso.pred2 <- predict(lasso.mod2,newx = Z,s="lambda.min")
dat$expTWLE.Lasso2[pos] <- as.vector(lasso.pred2)
# R2 bestimmen
varY.lasso.mod2 <- var(dat$expTWLE.Lasso2[pos])
R2.lasso.mod2 <- varY.lasso.mod2/varY
R2.lasso.mod2
# Ergebnistabelle
vv <- paste0("coef.stratum",st); tab4[,vv] <- NA
tab4[lasso.beta@i+1,vv] <- lasso.beta@x
vv <- paste0("lambda.stratum",st); tab4[,vv] <- lasso.mod2$lambda.min
vv <- paste0("R2.stratum",st); tab4[,vv] <- R2.lasso.mod2
}
# Regressionresiduen = Schätzung von SChul- und Unterrichtseffekt
dat$resTWLE.Lasso1 <- dat$TWLE - dat$expTWLE.Lasso1
dat$resTWLE.Lasso2 <- dat$TWLE - dat$expTWLE.Lasso2
# -------------------------------------------------------------
# Abschnitt 9.2.5.4, Ergänzung zum Buch
# Nichtparametrische Regression
#
#
# Achtung: Der nachfolgende Algorithmus benötigt viel Zeit!
#
av <- "TWLE" # Abhängige Variable
dfr3 <- NULL # Ergebnistabelle
# Variable für Leistungsschätzwerte
# Schleife über 4 Strata
for(st in 1:4){
# st <- 1
pos <- which(dat$stratum == st)
N <- length(pos)
schools <- dat$idschool[pos]
###
# Distanzmatrix dfr für alle Schulen im Stratum erstellen
dfr <- NULL
for (i in 1:N){
# i <- 1
# Teildatensatz von Schule i
dat.i <- dat[pos[i],c("idschool","TWLE",maineff)]
# Daten der Vergleichsgruppe
dat.vgl <- dat[pos[-i],c("idschool","TWLE",maineff)]
# Variablennamen von dat.vgl umbenennen
# names(dat.vgl) <- paste0("vgl.",names(dat.vgl))
# Variablennamen von dat.i umbenennen
names(dat.i) <- paste0(names(dat.i),".i")
# Daten zusammenfügen
index.vgl <- match(dat.vgl$idschool,schools)
dfr.i <- data.frame("index.i"=i,dat.i,
"index.vgl"=index.vgl,dat.vgl,
row.names=NULL)
# Distanz zur i
dfr.i$dist <- 0
gi <- c(1,1,1,1)
for(ii in 1:length(maineff)){
vv <- maineff[ii]
pair.vv <- grep(vv, names(dfr.i), value=T)
dist.vv <- gi[ii]*((dfr.i[,pair.vv[1]]-dfr.i[,pair.vv[2]])^2)
dfr.i$dist <- dfr.i$dist + dist.vv
}
print(i) ; flush.console()
dfr <- rbind( dfr , dfr.i )
}
dfr1 <- index.dataframe( dfr , systime=TRUE )
###
# h-Auswahl und Nichtparametrische Regression pro Schule i
dfr1.list <- list()
for (i in 1:N){
# i <- 1
dfr.i <- dfr[ dfr$index.i == i , ]
n <- nrow(dfr.i)
# Startwertliste für h initiieren
d.dist <- max(dfr.i$dist)-min(dfr.i$dist)
H <- c(seq(d.dist/100,d.dist,length=30),100000)
V1 <- length(H) # Anzahl der Startwerte in H
# Startwerte: Summe von w_ik
sumw <- 0*H
dfr0.i <- dfr.i[,c("idschool",av)]
# Schleife über alle h-Werte
for (ll in 1:V1 ){
h <- H[ll]
# Gewicht w_ik bei h
dfr.i$wgt.h <- dnorm(sqrt(dfr.i$dist), mean=0, sd=sqrt(h))
# Summe von w_ik bei h
sumw[which(H==h)] <- sum(dfr.i$wgt.h)
# Leave-one-out-Schätzer von Y_k
for (k in 1:n){
# Regressionsformel
fm <- paste0(av,"~",paste0(maineff,collapse="+"))
fm <- as.formula(fm)
# Regressionsanalyse ohne Beitrag von Schule k
dfr.i0 <- dfr.i[-k,]
mod.k <- lm(formula=fm,data=dfr.i0,weights=dfr.i0$wgt.h)
# Erwartungswert anhand Kovariaten der Schule k berechnen
pred.k <- predict(mod.k, dfr.i)[k]
dfr0.i[k,paste0( "h_",h) ] <- pred.k
}
print(paste0("i=",i,", h_",ll))
}
# Erwartungswerte auf Basis verschiedener h-Werte
dfr1 <- data.frame("idschool.i"=dfr.i$idschool.i[1],"h"=H )
# Berechnung des Kreuzvalidierungskriteriums
library(kerdiest)
hAL <- kerdiest::ALbw("n",dfr.i$dist) # Plug-in Bandbreite nach Altman und
# Leger
name <- paste0( "bandwidth_choice_school" , dfr.i$idschool.i[1] ,
"_cross.h_" , round2(hAL,1) )
# Regressionsgewichte auf Basis cross.h
dfr.i$cross.h <- hAL
dfr.i$crosswgt <- dnorm( sqrt(dfr.i$dist), mean=0, sd = sqrt(hAL) )
dfr.i <- index.dataframe( dfr.i , systime=TRUE )
# Kreuzvalidierungskriterium CVh
vh <- grep("h_",colnames(dfr0.i),value=TRUE)
for (ll in 1:V1){
# ll <- 5
dfr1[ll,"CVh"] <- sum( (dfr0.i[,av] - dfr0.i[,vh[ll]])^2 *
dfr.i$crosswgt) / n
print(ll)
}
# Bestimmung h.min
dfr1$min.h.index <- 0
ind <- which.min( dfr1$CVh )
dfr1$min.h.index[ind ] <- 1
dfr1$h.min <- dfr1$h[ind]
# Kleinste Quadratsumme der Schätzfehler
dfr1$CVhmin <- dfr1[ ind , "CVh" ]
# Effizienzsteigerung berechnen
dfr1$eff_gain <- 100 * ( dfr1[V1,"CVh"] / dfr1$CVhmin[1] - 1 )
# h auswählen
h <- dfr1$h.min[1]
# Gewichte anhand h berechnen
dfr.i$wgt.h <- dnorm( sqrt( dfr.i$dist ) , sd = sqrt( h) ) /
dnorm( 0 , sd = sqrt( h) )
dfr.i0 <- dfr.i
mod.ii <- lm(formula = fm,data = dfr.i0,weights = dfr.i0$wgt.h)
# Leistungsschätzwerte berechnen
predM <- data.frame(dfr.i[1,paste0(maineff,".i")])
names(predM) <- maineff
pred.ii <- predict( mod.ii , predM )
dfr1$fitted_np <- pred.ii
dfr1$h.min_sumwgt <- sum( dfr.i0$wgt.h )
dfr1$h_sumwgt <- sumw
# Leistungsschätzwerte zum Datensatz hinzufügen
dat$expTWLE.np[match(dfr1$idschool.i[1],dat$idschool)] <- pred.ii
dfr1.list[[i]] <- dfr1
}
###
# Ergebnisse im Stratum st zusammenfassen
dfr2 <- NULL
for(i in 1:length(dfr1.list)){
dat.ff <- dfr1.list[[i]]
dfr2.ff <- dat.ff[1,c("idschool.i","h.min","fitted_np","h.min_sumwgt",
"CVhmin","eff_gain")]
dfr2.ff$CVlinreg <- dat.ff[V1,"CVh"]
names(dfr2.ff) <- c("idschool","h.min","fitted_np","h.min_sumwgt",
"CVhmin","eff_gain","CVlinreg")
dfr2 <- rbind(dfr2, dfr2.ff)
print(i)
}
#---------------------------------------------------##
# R2 berechnen
varY <- var(dat$TWLE[pos])
varY.np <- var(dat$expTWLE.np[pos])
dfr2$R2.np <- varY.np/varY
#---------------------------------------------------##
# Zur Gesamtergebnistabelle
dfr3 <- rbind(dfr3,cbind("Stratum"=st,dfr2))
}
# Effizienz der NP-Regression gegenüber OLS-Regression
summary(dfr3$eff_gain)
table(dfr3$eff_gain > 5)
table(dfr3$eff_gain > 10)
table(dfr3$eff_gain > 20)
# Regressionsresiduen
dat$resTWLE.np <- dat$TWLE - dat$expTWLE.np
## -------------------------------------------------------------
## Abschnitt 9.2.6, Ergänzung zum Buch
## Ergebnisse im Vergleich
## -------------------------------------------------------------
# Output-Variablen
out <- grep("expTWLE",names(dat),value=T)
lt <- length(out)
# Korrelationsmatrix
tab <- tab1 <- as.matrix(round2(cor(dat[,out]),3))
# Varianzmatrix
tab2 <- as.matrix(round2(sqrt(var(dat[,out])),1))
tab3 <- matrix(NA,lt,lt)
# Differenzmatrix
for(ii in 1:(lt-1))
for(jj in (ii+1):lt) tab3[ii,jj] <- round2(mean(abs(dat[,out[jj]] -
dat[,out[ii]])),1)
tab4 <- matrix(NA,lt,lt)
# Differenzmatrix
for(ii in 1:(lt-1))
for(jj in (ii+1):lt) tab4[ii,jj] <- round2(sd(abs(dat[,out[jj]] -
dat[,out[ii]])),1)
# Ergebnistabelle
diag(tab) <- diag(tab2)
tab[upper.tri(tab)] <- tab3[upper.tri(tab3)]
# R2 Gesamt
varY <- var(dat$TWLE)
varexp.OLS1 <- var(dat$expTWLE.OLS1); R2.OLS1 <- varexp.OLS1/varY
varexp.OLS2 <- var(dat$expTWLE.OLS2); R2.OLS2 <- varexp.OLS2/varY
varexp.Lasso1 <- var(dat$expTWLE.Lasso1); R2.Lasso1 <- varexp.Lasso1/varY
varexp.Lasso2 <- var(dat$expTWLE.Lasso2); R2.Lasso2 <- varexp.Lasso2/varY
varexp.np <- var(dat$expTWLE.np); R2.np <- varexp.np/varY
R2 <- c(R2.OLS1,R2.OLS2,R2.Lasso1,R2.Lasso2,R2.np)
tab <- cbind(tab,R2)
# R2 pro Stratum
dat0 <- dat
for(st in 1:4){
# st <- 1
dat <- dat0[which(dat0$stratum == st),]
varY <- var(dat$TWLE)
varexp.OLS1 <- var(dat$expTWLE.OLS1); R2.OLS1 <- varexp.OLS1/varY
varexp.OLS2 <- var(dat$expTWLE.OLS2); R2.OLS2 <- varexp.OLS2/varY
varexp.Lasso1 <- var(dat$expTWLE.Lasso1); R2.Lasso1 <- varexp.Lasso1/varY
varexp.Lasso2 <- var(dat$expTWLE.Lasso2); R2.Lasso2 <- varexp.Lasso2/varY
varexp.np <- var(dat$expTWLE.np); R2.np <- varexp.np/varY
R2 <- c(R2.OLS1,R2.OLS2,R2.Lasso1,R2.Lasso2,R2.np)
tab <- cbind(tab,R2)
}
colnames(tab)[7:10] <- paste0("R2_stratum",1:4)
## -------------------------------------------------------------
## Abschnitt 9.2.7, Berücksichtigung der Schätzfehler
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 9.2.7, Listing 17: Bestimmung des Erwartungsbereichs
#
vv <- "expTWLE.OLS1" # Variablenname
mm <- "OLS1" # Kurzname des Modells
dfr <- NULL # Ergebnistabelle
# Schleife über alle möglichen Breite von 10 bis 60
for(w in 10:60){
# Variablen für Ergebnisse pro w
var <- paste0(mm,".pos.eb",w) # Position der Schule
var.low <- paste0(mm,".eblow",w) # Untere Grenze des EBs
var.upp <- paste0(mm,".ebupp",w) # Obere Grenze des EBs
# Berechnen
dat[,var.low] <- dat[,vv]-w/2 # Untere Grenze des EBs
dat[,var.upp] <- dat[,vv]+w/2 # Obere Grenze des EBs
# Position: -1=unterhalb, 0=innerhalb, 1=oberhalb des EBs
dat[,var] <- -1*(dat$TWLE < dat[,var.low]) + 1*(dat$TWLE > dat[,var.upp])
# Verteilung der Schulpositionen
tmp <- data.frame(t(matrix(prop.table(table(dat[,var])))))
names(tmp) <- c("unterhalb","innerhalb","oberhalb")
tmp <- data.frame("ModellxBereich"=var,tmp); dfr <- rbind(dfr,tmp) }
# Abweichung zur Wunschverteilung 25-50-25
dfr1 <- dfr
dfr1[,c(2,4)] <- (dfr1[,c(2,4)] - .25)^2
dfr1[,3] <- (dfr1[,3] - .5)^2
dfr1$sumquare <- rowSums(dfr1[,-1])
# Auswahl markieren
dfr$Auswahl <- 1*(dfr1$sumquare == min(dfr1$sumquare) )
# -------------------------------------------------------------
# Abschnitt 9.2.7, Ergänzung zum Buch
# Bestimmung des Erwartungsbereichs
#
# Ergebnisse aller Schulen werden aus Ursprungsdatensatz geladen.
dat <- datenKapitel09
# Liste der Erwartungswerte-Variablen
exp.vars <- grep("expTWLE",names(dat),value=T)
# Modellnamen
m.vars <- gsub("expTWLE.","",exp.vars, fixed = TRUE)
# Liste der Ergebnistabelle
list0 <- list()
# Ergebnisse
tab.erg <- NULL
# Schleife über alle Erwartungswerte aller Modelle
for(ii in 1:length(exp.vars)){
# ii <- 1
vv <- exp.vars[ii]
mm <- m.vars[ii]
# Ergebnistabelle
dfr <- NULL
# Schleife über alle möglichen Breite von 10 bis 60
for(w in 10:60){
# eb <- 10
var <- paste0(mm,".pos.eb",w) # Position der Schule
var.low <- paste0(mm,".eblow",w) # Untere Grenze des EBs
var.upp <- paste0(mm,".ebupp",w) # Obere Grenze des EBs
# Untere Grenze des EBs = Erwartungswert - w/2
dat[,var.low] <- dat[,vv]-w/2
# Obere Grenze des EBs = Erwartungswert + w/2
dat[,var.upp] <- dat[,vv]+w/2
# Position der Schule bestimmen
# -1 = unterhalb, 0 = innterhalb, 1 = oberhalb des EBs
dat[,var] <- -1*(dat$TWLE < dat[,var.low]) + 1*(dat$TWLE > dat[,var.upp])
# Verteilung der Positionen
tmp <- data.frame(t(matrix(prop.table(table(dat[,var])))))
names(tmp) <- c("unterhalb","innerhalb","oberhalb")
tmp <- data.frame("ModellxBereich"=var,tmp)
dfr <- rbind(dfr,tmp)
}
# Vergleich mit Wunschverteilung 25-50-25
dfr1 <- dfr
dfr1[,c(2,4)] <- (dfr1[,c(2,4)] - .25)^2
dfr1[,3] <- (dfr1[,3] - .5)^2
dfr1$sumquare <- rowSums(dfr1[,-1])
# Auswahl markieren
dfr$Auswahl <- 1*(dfr1$sumquare == min(dfr1$sumquare) )
# Zum Liste hinzufügen
list0[[ii]] <- dfr
print(dfr[which(dfr$Auswahl == 1),])
tab.erg <- rbind(tab.erg, dfr[which(dfr$Auswahl == 1),])
}
# Nur gewählte Ergebnisse im Datensatz beibehalten
all.vars <- grep("eb",names(dat),value=T)
# Untere und Obere Grenze mit speichern
eb.vars <- tab.erg[,1]
low.vars <- gsub("pos.eb","eblow",eb.vars)
upp.vars <- gsub("pos.eb","ebupp",eb.vars)
del.vars <- setdiff(all.vars, c(eb.vars,low.vars,upp.vars))
dat <- dat[,-match(del.vars,names(dat))]
## -------------------------------------------------------------
## Appendix: Abbildungen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abbildung 9.4
#
# Koeffizienten bei der ersten 50 lambdas ausdrucken
# Stratum 4
lambda <- lasso.mod2$lambda[1:50]
a <- round2(lambda,2)
a1 <- a[order(a)]
L <- length(a)
dfr <- NULL
for(ll in 1:L){
dfr.ll <- as.matrix(coef(lasso.mod2,newx = Z,s=a[ll] ))
colnames(dfr.ll) <- paste0("a_",ll)
dfr.ll <- data.frame("coef"=rownames(dfr.ll),dfr.ll)
rownames(dfr.ll) <- NULL
if(ll == 1) dfr <- dfr.ll else dfr <- merge(dfr, dfr.ll)
}
# Ohne Intercept
dfr <- dfr[-1,]
rownames(dfr) <- 1:nrow(dfr)
cl <- colors()
cl <- grep("grey",cl,value=T)
# Umgekehrte Reihenfolge
dfr1 <- dfr
for(x in 2:(L+1)) {dfr1[,x] <- dfr[,(L+3)-x];
names(dfr1)[x] <- names(dfr)[(L+3)-x]}
###
plot(x = log(a), y = rep(0,L), xlim = rev(range(log(a))), ylim=c(-20,22),
type = "l", xaxt ="n", xlab = expression(paste(lambda)),
ylab="Geschätzte Regressionskoeffizienten")
axis(1, at=log(a), labels=a,cex=1)
tmp <- nrow(dfr)
for(ll in 1:tmp){
# ll <- 1
lines(x=log(a),y=dfr[ll,2:(L+1)],type="l",pch=15-ll,col=cl[15-ll])
points(x=log(a),y=dfr[ll,2:(L+1)],type="p",pch=15-ll)
legend(x=2.8-0.7*(ll>tmp/2),y=25-2*(ifelse(ll>7,ll-7,ll)),
legend =dfr$coef[ll],pch=15-ll,bty="n",cex=0.9)
}
# Kennzeichung der gewählten lambda
v <- log(lasso.mod2$lambda.min)
lab2 <- expression(paste("ausgewähltes ",lambda," = .43"))
text(x=v+0.6,y=-8,labels=lab2)
abline(v = v,lty=2,cex=1.2)
# -------------------------------------------------------------
# Abbildung 9.5
# Auswahl Lambda anhand min(cvm)
#
xlab <- expression(paste(lambda))
plot(lasso.mod2, xlim = rev(range(log(lambda))),
ylim=c(550,1300),xlab=xlab,xaxt ="n",
ylab = "Mittleres Fehlerquadrat der Kreuzvalidierung (cvm)",
font.main=1,cex.main=1)
axis(1, at=log(a), labels=a,cex=1)
lab1 <- expression(paste(lambda," bei min(cvm)"))
text(x=log(lasso.mod2$lambda.min)+0.5,y=max(lasso.mod2$cvm)-50,
labels=lab1,cex=1)
lab2 <- expression(paste("(ausgewähltes ",lambda," = .43)"))
text(x=log(lasso.mod2$lambda.min)+0.6,y=max(lasso.mod2$cvm)-100,
labels=lab2,cex=1)
abline(v = log(lasso.mod2$lambda.min),lty=2)
text(x=log(lasso.mod2$lambda.min)-0.3,y = min(lasso.mod2$cvm)-30,
labels="min(cvm)",cex=1 )
abline(h = min(lasso.mod2$cvm),lty=2)
text <- expression(paste("Anzahl der Nicht-null-Koeffizienten (",
lambda," entsprechend)"))
mtext(text=text,side=3,line=3)
# -------------------------------------------------------------
# Abbildung 9.6
# Rohwert-Schätzwert Schule 1196 & 1217 im Vergleich
#
id <- c(1196, 1217)
par(mai=c(1.2,3,1,.5))
plot(x=rep(NA,2),y=c(1:2),xlim=c(470,610),yaxt ="n",type="l",
xlab="Erwartungswerte je nach Modell und Schulleistung",ylab="")
legend <- c("Schulleistung (TWLE)",paste0("", c("OLS1","OLS2","Lasso1",
"Lasso2","NP"),
"-Modell"))
axis(2, at=c(seq(1,1.4,0.08),seq(1.6,2,0.08)), las=1,cex=0.7,
labels=rep(legend,2))
text <- paste0("Schule ",id)
mtext(text=text,side=2,at = c(1.2,1.8),line = 10)
exp.vars <- c("TWLE",
paste0("expTWLE.", c("OLS1","OLS2","Lasso1","Lasso2","np")))
pch = c(19, 0,3,2,4,5)
ii <- 1
col = c("grey", rep("lightgrey",5))
for(vv in exp.vars){
# vv <- "TWLE"
x <- dat0[which(dat0$idschool %in% id),vv]
abline(h = c(0.92+ii*0.08,1.52+ii*0.08), lty=1+1*(ii>1),col=col[ii])
points(x=x,y=c(0.92+ii*0.08,1.52+ii*0.08),type="p",pch=pch[ii])
ii <- ii + 1
}
## End(Not run)
Kapitel 10: Reporting und Analysen
Description
Das ist die Nutzerseite zum Kapitel 10, Reporting und Analysen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenefalls erweitert.
Author(s)
Michael Bruneforth, Konrad Oberwimmer, Alexander Robitzsch
References
Bruneforth, M., Oberwimmer, K. & Robitzsch, A. (2016). Reporting und Analysen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 333–362). Wien: facultas.
See Also
Zu datenKapitel10
, den im Kapitel verwendeten Daten.
Zurück zu Kapitel 9
, Fairer Vergleich in der Rückmeldung.
Zu Kapitel 11
, Aspekte der Validierung.
Zur Übersicht
.
Examples
## Not run:
library(BIFIEsurvey)
library(matrixStats)
data(datenKapitel10)
dat <- datenKapitel10$dat
dat.roh <- datenKapitel10$dat.roh
dat.schule <- datenKapitel10$dat.schule
dat.schule.roh <- datenKapitel10$dat.schule.roh
## -------------------------------------------------------------
## Abschnitt 10.4.1: Datenbasis
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.4.1 a, Ergänzung zum Buch
# Herunterladen, entpacken und setzen des Arbeitsspeichers
#
# setwd(dir = ".../DatenKapitel10")
# -------------------------------------------------------------
# Abschnitt 10.4.1, Listing 1: Einlesen der Schülerdaten
#
# Anlegen eines leeren Listenobjektes für Schülerdaten
dat <- list()
# Vektor mit Liste der Dateinamen für Schülerdaten
dateinamen <- paste0("e8pv__schueler_imp_",1:10,".csv")
# Schleife zum Einlesen der Daten, die in die Listenobjekte
# abgelegt werden
for (ii in 1:10) {
schueler_dfr<-read.csv2(file = dateinamen[[ii]])
dat[[ii]] <- schueler_dfr
}
# Überprüfen des Listenobjektes und der eingelesenen Daten
str(dat)
# Rohdaten als Datenmatrix einlesen
dat.roh <- read.csv2(file = "e8pv__schueler_raw.csv")
# -------------------------------------------------------------
# Abschnitt 10.4.1, Listing 1a: Ergänzung zum Buch
# Einlesen der Schulendaten
#
# Anlegen eines leeren Listenobjektes für Schuldaten
dat.schule <- list()
# Vektor mit Liste der Dateinamen für Schuldaten
dateinamen <- paste0("e8pv__schule_imp_",1:10,".csv")
# Schleife zum Einlesen der Daten, die in die Listenobjekte
# abgelegt werden
for (ii in 1:10) {
schule_dfr<-read.csv2(file = dateinamen[[ii]])
dat.schule[[ii]] <- schule_dfr
}
# Überprüfen des Listenobjektes und der eingelesenen Daten
str(dat.schule)
#Rohdaten als Datenmatrix einlesen
dat.schule.roh <- read.csv2(file = "e8pv__schule_raw.csv")
## -------------------------------------------------------------
## Abschnitt 10.4.2: Merging verschiedener Ebenen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.4.2, Listing 1
#
for (i in 1:10) {
dat[[i]] <- merge(dat[[i]],dat.schule[[i]],
by = "idschool",all.x = TRUE)
}
# -------------------------------------------------------------
# Abschnitt 10.4.2, Listing 2
for (i in 1:10) {
dat.agg <- aggregate(dat[[i]][,c("HISEI","E8RPV")],
by = list(idschool = dat[[i]]$idschool),
FUN = mean,na.rm = TRUE)
dat.schule[[i]] <- merge(dat.schule[[i]],dat.agg,
by="idschool",all.x = TRUE)
}
## -------------------------------------------------------------
## Abschnitt 10.4.3: Erzeugen von BIFIEdata-Objekten
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.4.3, a: Ergänzung zum Buch
# Einlesen der Replikationsgewichte
#
# Zwischenspeichern des Schülerdatensatzes
dat.tmp <- dat
# Daten aus Large-Scale Assessments können mit replicate weights
# abgespeichert werden (z.B. PISA) oder mit Informationen zu den
# Jackknifezonen und -gewichten (z.B. PIRLS). In diesem Beispiel
# werden beide Methoden vorgestellt, daher wird die Gewichtungs-
# information in beiden Formen eingelesen: mit replicate weights
# im Datensatz dat1; mit Replikationsdesign im Datensatz dat2.
# replicate weights für Schüler/innen als Datenmatrix einlesen
dat.repwgts <- read.csv2(file = "e8__schueler_repwgts.csv")
# replicate weights an Schülerdaten mergen
for (ii in 1:10) {
dat[[ii]]<-merge(x = dat[[ii]],y = dat.repwgts,
by = c("idschool","idstud"))
}
# Jackknifezonen und -gewichte für Schulen als Datenmatrix einlesen
dat2 <- list()
dat.schule.jk <- read.csv2(file = "e8__schule_jkzones.csv")
# Jackknifezonen und -gewichte an schülerdaten mergen
for (ii in 1:10) {
dat2[[ii]]<-merge(x = dat.tmp[[ii]],y = dat.schule.jk,
by = "idschool")
}
# -------------------------------------------------------------
# Abschnitt 10.4.3, b: Ergänzung zum Buch
# Kontrolle der Sortierung
#
# Die Observationen in den 10 Imputationen muessen gleich sortiert
# sein. Dies wir zur Sicherheit getestet.
for (i in 2:10) {
if (sum(dat[[1]]$idstud!=dat[[i]]$idstud )>0)
stop("Imputationsdatensätze nicht gleich sortiert!")
}
# -------------------------------------------------------------
# Abschnitt 10.4.3, c: Ergänzung zum Buch
# Verwendung des R-Datenobjekts
#
dat <- datenKapitel10$dat
# -------------------------------------------------------------
# Abschnitt 10.4.3, Listing 1: Übernahme der Gewichte aus
# Datenmatrix
#
wgtstud <- dat[[1]]$wgtstud
repwgtsvar <- grep("^w_fstr",colnames(dat[[1]]))
repwgts <- dat[[1]][,repwgtsvar]
dat <- BIFIE.data(data.list = dat,wgt = wgtstud,
wgtrep = repwgts,fayfac = 1,
cdata = TRUE)
summary(dat)
# -------------------------------------------------------------
# Abschnitt 10.4.3, Listing 2: Erzeugung der Gewichte aus
# Replikationsdesign
#
dat2 <- BIFIE.data.jack(data = dat2,wgt = "wgtstud",
jktype = "JK_GROUP",
jkzone = "jkzone",
jkrep = "jkrep",
fayfac = 1)
summary(dat2)
# -------------------------------------------------------------
# Abschnitt 10.4.3, Listing 3: Univariate Statistik Reading
#
res.univar <- BIFIE.univar(BIFIEobj = dat,
vars = c("E8RPV"),
group = "Strata")
summary(res.univar)
res2.univar <- BIFIE.univar(BIFIEobj = dat2,
vars = c("E8RPV"),
group = "Strata")
summary(res2.univar)
## -------------------------------------------------------------
## Abschnitt 10.4.4: Rekodierung und Transformation von
## Variablen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.4.4, Listing 1: Neue Variable GERSER mit
# BIFIE.data.transform
#
transform.formula <- as.formula(
"~ 0 + I(cut(E8RPV,breaks = c(0,406,575,1000),labels = FALSE))"
)
dat <- BIFIE.data.transform(dat,transform.formula,
varnames.new = "GERSER")
res.freq <- BIFIE.freq(BIFIEobj = dat,vars = c("GERSER"))
summary(res.freq)
# -------------------------------------------------------------
# Abschnitt 10.4.4, Listing 2: Zwei neue Variablen PVERfit und
# PVERres mit BIFIE.data.transform
#
transform.formula <- as.formula(
"~ 0 + I(fitted(lm(E8RPV ~ HISEI + female))) +
I(residuals(lm(E8RPV ~ HISEI + female)))"
)
dat <- BIFIE.data.transform(dat,transform.formula,
varnames.new = c("PVERfit","PVERres"))
res.univar <- BIFIE.univar(BIFIEobj = dat,
vars = c("PVERfit","PVERres"))
summary(res.univar)
## -------------------------------------------------------------
## Abschnitt 10.4.5: Berechnung von Kenngroessen und deren
## Standardfehlern
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.4.5, Listing 1: Anwenderfunktion
#
library(matrixStats)
anwenderfct.weightedMad <- function(X,w)
{
# Die Funktion weightedMad wird auf jede Spalte der
# übergebenen Matrix X angewendet.
Wmad<-apply(X = X, MARGIN = 2,FUN = matrixStats::weightedMad,
w = w, na.rm = T)
}
wgt.Mad <- BIFIE.by(BIFIEobj = dat,
vars = c("HISEI", "E8RPV"),
userfct = anwenderfct.weightedMad,
userparnames = c("wMadHISEI", "wMadE8RPV"))
summary(wgt.Mad)
## -------------------------------------------------------------
## Abschnitt 10.6.1: Datenexploration
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.6.1, Listing 1: Ungewichtete univariate
# Statistiken
#
# Ungewichtete univariate Statistiken
# Häufigkeitstabelle zu 'eltausb' und 'migrant' (Kreuztabelle)
tab1 <- table(dat.roh[,c("eltausb","migrant")],useNA = "always")
# Ausgabe der Tabelle, ergänzt um Randsummen
addmargins(tab1, FUN = list(Total = sum), quiet = TRUE)
# Ausgabe der Tabelle als Prozentverteilungen
# (in Prozent, gerundet)
round(addmargins(prop.table(x = tab1), FUN = list(Total = sum),
quiet = TRUE)*100,2)
# Ausgabe mit Prozentverteilungen der Spalten bzw. Zeilen
# (in Prozent, gerundet)
round(prop.table(x = tab1,margin = 2)*100,2)
round(prop.table(x = tab1,margin = 1)*100,2)
# Ausgabe nicht wiedergegeben
# -------------------------------------------------------------
# Abschnitt 10.6.1, Listing 2: Gewichtete univariate
# Statistiken an imputierten Daten
# Gewichtete univariate Statistiken an imputierten Daten
# Häufigkeitstabelle zu 'eltausb' und 'migrant'
res1 <- BIFIE.freq(BIFIEobj = dat,vars = c("eltausb","migrant"))
summary(res1)
# Häufigkeitstabelle zu 'eltausb' gruppiert nach 'migrant'
res2 <- BIFIE.freq(BIFIEobj = dat,vars = "eltausb",
group = "migrant")
summary(res2)
# Kreuztabelle mit zwei Variablen
res3 <- BIFIE.crosstab(BIFIEobj = dat,vars1 = "eltausb",
vars2 = "migrant")
summary(res3)
# -------------------------------------------------------------
# Abschnitt 10.6.1, Listing 3: Export der Tabelle
#
res_export <- res1$stat[,c("var","varval","Ncases","Nweight",
"perc","perc_SE")]
colnames(res_export) <- c("Variable","Wert","N (ungewichtet)",
"N gewichtet)","Prozent","Standardfehler")
write.table(x = res_export,file = "res_export.dat", sep = ";",
dec = ",", row.names = FALSE)
## -------------------------------------------------------------
## Abschnitt 10.6.2: Analyse fehlender Werte
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.6.2, Listing 1: Fehlende Werte
#
res1 <- BIFIE.mva(dat, missvars = c("eltausb","migrant"),
se = TRUE)
summary(res1)
# -------------------------------------------------------------
# Abschnitt 10.6.2, Listing 2: Fehlende Werte unter Kovariaten
#
res2 <- BIFIE.mva(dat,missvars = c("eltausb","migrant"),
covariates = c("E8RTWLE","eltausb", "migrant"), se = TRUE)
summary(res2)
## -------------------------------------------------------------
## Abschnitt 10.6.3: Mittelwerte, Perzentilbaender und Quantile
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.6.3, Listing 1: Hilfsvariable
#
# Hilfsvariable zur Gruppierung anlegen
transform.formula <- as.formula("~ 0 + I(migrant*10+female)")
dat <- BIFIE.data.transform(dat,transform.formula,
varnames.new="migrant_female")
# -------------------------------------------------------------
# Abschnitt 10.6.3, Listing 2: Statistiken an Hilfsvariablen
#
# Univariate Statistiken mit Mittelwerten und Standardfehlern
res1 <- BIFIE.univar(BIFIEobj = dat,vars = "E8RPV",
group = "migrant_female")
# summary(res1)
mittelwerte<-res1$stat[,c("groupval","M","M_SE")]
# Berechne Quantile
probs<-c(.05,.25,.75,.95)
res2 <- BIFIE.ecdf(BIFIEobj = dat,breaks = probs,
quanttype = 1, vars = "E8RPV",
group = "migrant_female")
# summary(res2)
quantile<-data.frame(t(matrix(res2$output$ecdf,nrow = 4)))
colnames(quantile)<-probs
# Führe Ergebnisse zusammen
res3<-cbind(mittelwerte,quantile)
print(res3)
# -------------------------------------------------------------
# Abschnitt 10.6.3, Listing 3: IQA
#
# Berechne Interquartilabstand (IQA)
res3$IQA<-res3$"0.75"-res3$"0.25"
# Berechne Grenzen des Vertrauensintervals
res3$VIunten<-res3$M-2*res3$M_SE
res3$VIoben<-res3$M+2*res3$M_SE
round(res3,1)
## -------------------------------------------------------------
## Abschnitt 10.6.4: Gruppenvergleiche mit Regressionen
## -------------------------------------------------------------
# -------------------------------------------------------------
# Abschnitt 10.6.4, Listing 1: Gruppenvergleich Geschlecht
#
# Gruppenvergleich Geschlecht, gesamte Population
res1 <- BIFIE.linreg(BIFIEobj = dat, formula = E8RPV ~ female)
# Alternativer Aufruf mit identischem Resultat
res1 <- BIFIE.linreg(BIFIEobj = dat,dep = "E8RPV",
pre = c("one","female"))
# Vollständige Ausgabe
summary(res1)
# Reduzierte Ausgabe der Ergebnisse
res1_short <- res1$stat[res1$stat$parameter == "b" &
res1$stat$var == "female",c("est","SE")]
colnames(res1_short) <- c("Geschlechterunterschied","SE")
res1_short
# Gruppenvergleich Geschlecht getrennt nach 'migrant'
res2 <- BIFIE.linreg(BIFIEobj = dat,
formula = E8RPV ~ female,
group = "migrant")
# Vollständige Ausgabe
summary(res2)
# Reduzierte Ausgabe der Ergebnisse
res2_short <- res2$stat[res2$stat$parameter == "b" &
res2$stat$var == "female",
c("groupval","est","SE")]
colnames(res2_short) <- c("Migrant","Geschlechterunterschied",
"SE")
res2_short
# -------------------------------------------------------------
# Abschnitt 10.6.4, Listing 2: Wald-Test
#
res3 <- BIFIE.univar(vars = "E8RPV",BIFIEobj = dat,
group = c("migrant","female"))
res3_wald <- BIFIE.univar.test(BIFIE.method = res3)
# summary(res3_wald)
res3_wald$stat.dstat[,c("group","groupval1","groupval2",
"M1","M2","d","d_SE","d_t","d_p")]
# -------------------------------------------------------------
# Abschnitt 10.6.4, Listing 3: Kontrolle um soziale Herkunft
#
# Gruppenvergleich ohne Berücksichtigung der sozialen Herkunft
res1 <- BIFIE.linreg(BIFIEobj = dat, formula = E8RPV ~ migrant)
# summary(res1)
res1$stat[res1$stat$parameter == "b" & res1$stat$var == "migrant",
c("groupval","est","SE")]
# Gruppenvergleich mit Berücksichtigung der sozialen Herkunft
res2 <- BIFIE.linreg(BIFIEobj = dat,
formula = E8RPV ~ migrant+HISEI+eltausb+buch)
# summary(res2)
res2$stat[res2$stat$parameter == "b" & res2$stat$var == "migrant",
c("groupval","est","SE")]
## End(Not run)
Kapitel 11: Aspekte der Validierung
Description
Das ist die Nutzerseite zum Kapitel 11, Aspekte der Validierung, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung. Im Abschnitt Details werden die im Kapitel verwendeten R-Syntaxen zur Unterstützung für Leser/innen kommentiert und dokumentiert. Im Abschnitt Examples werden die R-Syntaxen des Kapitels vollständig wiedergegeben und gegebenenfalls erweitert.
Details
Dieses Kapitel enthält keine Beispiele mit R.
Author(s)
Robert Fellinger, Thomas Kiefer, Alexander Robitzsch, Matthias Trendtel
References
Fellinger, R., Kiefer, T., Robitzsch, A. & Trendtel, M. (2016). Aspekte der Validierung. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 363–398). Wien: facultas.
See Also
Zurück zu Kapitel 10
, Reporting und Analysen.
Zur Übersicht
.
Large-Scale Assessment mit R: Hilfsfunktionen aus den Kapiteln
Description
Das ist die Nutzerseite zu den Hilfsfunktionen, die in einigen Kapiteln im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung angewendet werden.
Usage
zones.within.stratum(offset, n.str)
covainteraction(dat,covas, nchar)
quintfunct(X,w)
Arguments
offset |
siehe |
n.str |
siehe |
dat |
siehe |
covas |
siehe |
nchar |
siehe |
X |
|
w |
|
Illustrationsdaten zu Kapitel 1, Testkonstruktion
Description
Hier befindet sich die Dokumentation der in Kapitel 1, Testkonstruktion, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel01)
Format
datenKapitel01
ist eine Liste mit den vier Elementen pilotScored
,
pilotItems
, pilotRoh
und pilotMM
, die einer fiktiven
Pilotierung entstammen.
-
pilotScored: Rekodierte Instrumentendaten der Pilotierung (vgl.
pilotItems
).sidstud
Schüleridentifikator. female
Geschlecht ( "w"
= weiblich,"m"
= männlich).form
das von der Schülerin/dem Schüler bearbeitete Testheft. E8RS*
dichotom und polytom bewertete Itemantworten auf Items E8RS13151
bisE8RS7993
(0:4
= Score der Itemantwort,8
= Itemantwort "nicht bewertbar",9
= "omitted response").'data.frame': 2504 obs. of 163 variables: $ sidstud : int 1052 1057 1058 1064 1068 1073 1074 1076 1078 1080 ... $ female : chr "w" "w" "w" "w" ... $ form : chr "PR019" "PR020" "PR021" "PR022" ... $ E8RS13151: int NA NA NA NA NA NA NA NA NA NA ... $ E8RS13171: int NA NA 1 NA NA NA NA 1 NA NA ... $ E8RS13491: int NA NA NA NA 0 NA NA NA NA NA ... $ E8RS13641: int 0 NA NA NA NA NA 0 NA NA NA ... [...] $ E8RS7929: int NA NA 0 NA NA NA NA NA NA NA ... $ E8RS7940: int NA NA NA NA NA 0 NA NA NA NA ... $ E8RS7955: int NA 0 NA NA NA NA NA NA 2 NA ... $ E8RS7993: int NA NA NA 0 NA NA 2 NA NA NA ...
-
pilotItems: Itembank der Pilotierung.
testlet
Testletname des Items (gleichbedeutend mit zugewiesenem Stimulus). item
Itemname. format
Antwortformt. focus
Fokus des Testitems. focusLabel
Bezeichnung des Fokus des Testitems. topic
Thema. no.Words
Anzahl Wörter im Stimulus. key
Indikator der richtigen Antwort ( 1:3
= korrekte Antwortoption bei Multiple-Choice Items,A:F
= korrekt zuzuordnende Antwortoption bei Matching-Items,""
= korrekte Antworten für Items im Antwortformat "open gap-fill" werden in Form von Coding-Guides ausgebildeten Kodiererinnen/Kodierern vorgelegt).maxScore
Maximal zu erreichende Punkte. PR*
Positionen der Items in den Testheften PR001
bisPR056
.'data.frame': 320 obs. of 65 variables: $ testlet : chr "E8RS1315" "E8RS1317" "E8RS1340" "E8RS1349" ... $ item : chr "E8RS13151" "E8RS13171" "E8RS13401" "E8RS13491" ... $ format : chr "MC3" "MC3" "MC3" "MC3" ... $ focus : int 1 1 1 1 1 1 1 1 1 1 ... $ focusLabel: chr "RFocus1" "RFocus1" "RFocus1" "RFocus1" ... $ topic : chr "Interkulturelle und landeskundliche Aspekte" "Familie und Freunde" ... $ no.Words : int 24 24 29 32 10 33 22 41 10 37 ... $ key : chr "1" "3" "2" "2" ... $ maxScore : int 1 1 1 1 1 1 1 1 1 1 ... $ PR001 : int NA NA NA 10 NA NA NA NA NA NA ... $ PR002 : int 5 NA 6 NA 7 NA NA 8 NA NA ... $ PR003 : int NA NA NA 6 NA NA NA NA NA NA ... $ PR004 : int NA NA NA 10 NA NA NA NA NA NA ... [...] $ PR054 : int NA NA NA NA NA NA NA NA NA NA ... $ PR055 : int NA 9 NA NA NA NA 10 NA NA 11 ... $ PR056 : int NA NA NA NA NA NA NA NA 6 NA ...
-
pilotRoh: Instrumentendaten der Pilotierung mit Roh-Antworten (vgl.
pilotItems
).sidstud
eindeutiger Schüleridentifikator. female
Geschlecht ( "w"
= weiblich,"m"
= männlich).form
das von der Schülerin/dem Schüler bearbeitete Testheft. E8RS*
Rohantworten der Schülerin/des Schülers auf Items E8RS13151
bisE8RS37281
((8, 9)
= für alle Items, wie oben, nicht bewertbare bzw. ausgelassene Itemantwort,1:3
= gewählte Antwortoption bei Multiple-Choice Items,A:F
= zugeordnete Antwortoption bei Matching-Items,0:1
= von Kodiererinnen/Kodierern bewertete Antworten für Items im Antwortformat "open gap-fill").'data.frame': 2504 obs. of 323 variables: $ sidstud : int 1052 1057 1058 1064 1068 1073 1074 1076 1078 1080 ... $ female : chr "w" "w" "w" "w" ... $ form : chr "PR019" "PR020" "PR021" "PR022" ... $ E8RS13151: int NA NA NA NA NA NA NA NA NA NA ... $ E8RS13171: int NA NA 3 NA NA NA NA 3 NA NA ... $ E8RS13491: int NA NA NA NA 3 NA NA NA NA NA ... $ E8RS13641: int 2 NA NA NA NA NA 2 NA NA NA ... [...] $ E8RS37163: chr "" "" "" "" ... $ E8RS37164: chr "" "" "" "" ... $ E8RS37165: chr "" "" "" "" ... $ E8RS37281: chr "" "" "" "" ...
-
pilotMM: Multiple-Marking-Datensatz der Pilotierung mit gemeinsamen Bewertungen einer itemweisen Auswahl von Schülerantworten durch alle Kodiererinnen/Kodierer (
0
= falsch,1
= richtig,(8, 9)
= wie oben, nicht bewertbare bzw. ausgelassene Itemantwort).sidstud
Schüleridentifikator. item
Itemnummer. Coder_1
Bewertung der Schülerantwort von Kodiererin/Kodierer 1. Coder_2
Bewertung der Schülerantwort von Kodiererin/Kodierer 2. Coder_3
Bewertung der Schülerantwort von Kodiererin/Kodierer 3. 'data.frame': 1200 obs. of 5 variables: $ sidstud: int 1185 1269 1311 1522 1658 1665 1854 1889 1921 2067 ... $ item : chr "E8RS46051" "E8RS46051" "E8RS46051" "E8RS46051" ... $ Coder_1: int 1 1 9 0 0 9 9 1 9 0 ... $ Coder_2: int 1 1 9 0 0 9 9 1 9 0 ... $ Coder_3: int 1 1 9 0 0 9 9 1 9 0 ...
References
Itzlinger-Bruneforth, U., Kuhn, J.-T. & Kiefer, T. (2016). Testkonstruktion. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 21–50). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 1
.
Illustrationsdaten zu Kapitel 2, Stichprobenziehung
Description
Hier befindet sich die Dokumentation der in Kapitel 2, Stichprobenziehung, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel02)
Format
datenKapitel02
ist eine Liste mit den zwei Elementen schueler
und
schule
, die auf Schulen- und Schülerebene alle für eine
Stichprobenziehung und die Berechnung von Stichprobengewichten relevanten
Informationen beinhalten.
Diese 51644 Schülerinnen und Schüler in 1327 Schulen – verteilt über vier Strata – stellen die Zielpopulation der im Band durchgeführten Analysen dar.
-
schueler: Schülerdatensatz.
SKZ
Schulenidentifikator ("Schulkennzahl"). klnr
Nummer der Klasse innerhalb der Schule. idclass
Klassenidentifikator. idstud
Schüleridentifikator. female
Geschlecht ( 1
= weiblich,0
= männlich).Stratum
Stratum der Schule. ( 1:4
= Stratum 1 bis Stratum 4; für eine genauere Beschreibung der Strata, siehe Buchkapitel).teilnahme
Information über die Teilnahme der Schülerin/ des Schülers an der Erhebung ( 1
= nimmt teil,0
= nimmt nicht teil). Information ist erst zum Zeitpunkt der Erhebung vorhanden (nicht schon bei der Stichprobenziehung) und wird zur Berechnung der Stichprobengewichte mit Ausfalladjustierung herangezogen (siehe Buchkapitel, Unterabschnitt 2.4.4).'data.frame': 51644 obs. of 7 variables: $ SKZ : int [1:51644] 10001 10001 10001 10001 10001 10001 10001 10001 10001 10001 ... $ klnr : int [1:51644] 1 1 1 1 1 1 1 1 1 1 ... $ idclass : int [1:51644] 1000101 1000101 1000101 1000101 1000101 1000101 1000101 1000101 ... $ idstud : int [1:51644] 100010101 100010102 100010103 100010104 100010105 100010106 100010107 ... $ female : int [1:51644] 1 0 0 0 0 1 0 1 0 1 ... $ Stratum : int [1:51644] 1 1 1 1 1 1 1 1 1 1 ... $ teilnahme: int [1:51644] 1 1 1 1 0 1 1 1 1 1 ...
-
schule: Schulendatensatz.
index
Laufparameter. SKZ
Schulenidentifikator ("Schulkennzahl"). stratum
Stratum der Schule. ( 1:4
= Stratum 1 bis Stratum 4; für eine genauere Beschreibung der Strata, siehe Buchkapitel).NSchueler
Anzahl Schüler/innen in der 4. Schulstufe der Schule. NKlassen
Anzahl Klassen in der 4. Schulstufe der Schule. 'data.frame': 1327 obs. of 5 variables: $ index : int [1:1327] 1 2 3 4 5 6 7 8 9 10 ... $ SKZ : int [1:1327] 10204 10215 10422 11017 10257 10544 10548 10846 11127 10126 ... $ stratum : int [1:1327] 1 1 1 1 1 1 1 1 1 1 ... $ NSchueler: int [1:1327] 8 9 9 9 10 10 10 10 10 11 ... $ NKlassen : int [1:1327] 1 1 1 1 1 1 1 2 1 1 ...
References
George, A. C., Oberwimmer, K. & Itzlinger-Bruneforth, U. (2016). Stichprobenziehung. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 51–81). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 2
.
Illustrationsdaten zu Kapitel 3, Standard-Setting
Description
Hier befindet sich die Dokumentation der in Kapitel 3, Standard-Setting, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel03)
Format
datenKapitel03
ist eine Liste mit den vier Elementen ratings
,
bookmarks
, sdat
und productive
, die Daten zu verschiedenen
Methoden eines Standard-Settings beinhalten.
Normierte Personen- und Itemparameter entstammen einer Vorgängerstudie, in der die Parameter für das jeweils zu betrachtende Testinstrument auf die Berichtsmetrik transformiert wurden (vgl. Kapitel 5, Testdesign, und Kapitel 6, Skalierung und Linking, im Band).
-
ratings: Daten aus der IDM-Methode (siehe Buchkapitel, Unterabschnitt 3.2.2).
task
Itemnummer. Norm_rp23
Itemparameter auf der Berichtsmetrik. Seite_OIB
Seitenzahl im OIB. R01...R12
Von der jeweiligen Expertin/dem jeweiligen Experten (Rater/in) zugeordnete Kompetenzstufe des Items. 'data.frame': 60 obs. of 15 variables: $ task : chr [1:60] "E8RS89991" "E8RS14021" "E8RS16031" "E8RS14171" ... $ Norm_rp23: num [1:60] 376 396 396 413 420 ... $ Seite_OIB: int [1:60] 1 2 3 4 5 6 7 8 9 10 ... $ R01 : int [1:60] 1 1 1 1 1 1 1 1 1 1 ... $ R02 : int [1:60] 1 1 1 2 1 2 2 1 2 2 ... $ R03 : int [1:60] 1 2 1 2 1 2 2 1 1 2 ... $ R04 : int [1:60] 1 1 1 1 2 1 1 1 2 1 ... $ R05 : int [1:60] 2 2 1 2 1 1 2 1 2 2 ... $ R06 : int [1:60] 1 1 1 1 2 1 2 1 2 2 ... $ R07 : int [1:60] 1 1 1 1 1 1 1 1 1 2 ... $ R08 : int [1:60] 2 2 1 2 2 2 2 1 2 2 ... $ R09 : int [1:60] 2 1 1 1 1 1 2 1 2 2 ... $ R10 : int [1:60] 1 2 1 1 1 1 1 1 2 1 ... $ R11 : int [1:60] 2 2 1 1 2 2 2 1 2 1 ... $ R12 : int [1:60] 1 2 1 2 3 2 2 1 1 2 ...
-
bookmarks: Daten aus der Bookmark-Methode (siehe Buchkapitel, Unterabschnitt 3.2.3).
Rater
Rateridentifikator der Expertin/des Experten im Panel. Cut1
Bookmark der Expertin/des Experten in Form einer Seite im OIB, wo ein Schüler an der Grenze zwischen der ersten und zweiten Stufe das Item nicht mehr sicher lösen könnte (für eine genauere Beschreibung der Stufen, siehe Buchkapitel). Cut2
Entsprechender Bookmark für die Grenze zwischen zweiter und dritter Stufe. 'data.frame': 12 obs. of 3 variables: $ Rater: chr [1:12] "R01" "R02" "R03" "R04" ... $ Cut1 : int [1:12] 6 4 6 2 4 4 4 4 3 6 ... $ Cut2 : int [1:12] 45 39 39 45 39 30 39 39 44 45 ...
-
sdat: Plausible Values zum Berichten von Impact Data (siehe Buchkapitel, Unterabschnitt 3.2.4).
pid
Schüleridentifikator. studwgt
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2, Stichprobenziehung, im Band). TPV1...TPV10
Plausible Values der Schülerin/des Schülers auf der Berichtsmetrik (vgl. Kapitel 8, Fehlende Daten und Plausible Values, im Band). 'data.frame': 3500 obs. of 12 variables: $ pid : int [1:3500] 1 2 3 4 5 6 7 8 9 10 ... $ studwgt: num [1:3500] 0.978 0.978 0.978 0.978 0.978 ... $ TPV1 : num [1:3500] 635 562 413 475 427 ... $ TPV2 : num [1:3500] 601 558 409 452 462 ... $ TPV3 : num [1:3500] 512 555 383 444 473 ... $ TPV4 : num [1:3500] 675 553 375 473 454 ... $ TPV5 : num [1:3500] 595 553 384 471 457 ... $ TPV6 : num [1:3500] 593 557 362 490 501 ... $ TPV7 : num [1:3500] 638 518 292 460 490 ... $ TPV8 : num [1:3500] 581 493 306 467 477 ... $ TPV9 : num [1:3500] 609 621 333 448 462 ... $ TPV10 : num [1:3500] 573 634 406 537 453 ...
-
productive: Daten aus der Contrasting-Groups-Methode (siehe Buchkapitel, Unterabschnitt 3.3.2).
Script
Nummer des Schülertexts. Performance
Personenparameter der Schülerin/des Schülers auf der Berichtsmetrik. R01...R10
Von der jeweiligen Expertin/dem jeweiligen Experten (Rater/in) zugeordnete Kompetenzstufe der Performanz ( 0
= untere Stufe,1
= obere Stufe; für eine genauere Beschreibung der Stufen, siehe Buchkapitel).'data.frame': 45 obs. of 12 variables: $ Script : int [1:45] 1 2 3 4 5 6 7 8 9 10 ... $ Performance: num [1:45] 211 260 269 308 321 ... $ R01 : int [1:45] 1 0 0 1 0 0 0 0 0 0 ... $ R02 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R03 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R04 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R05 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R06 : int [1:45] 1 0 0 0 0 0 1 0 0 0 ... $ R07 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R08 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R09 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ... $ R10 : int [1:45] 0 0 0 0 0 0 0 0 0 0 ...
References
Luger-Bazinger, C., Freunberger, R. & Itzlinger-Bruneforth, U. (2016). Standard-Setting. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 83–110). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 3
.
Illustrationsdaten zu Kapitel 4, Differenzielles Itemfunktionieren in Subgruppen
Description
Hier befindet sich die Dokumentation der in Kapitel 4, Differenzielles Itemfunktionieren in Subgruppen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel04)
Format
datenKapitel04
ist eine Liste mit den drei Elementen dat
,
dat.th1
und ibank
.
-
dat: Dichotome Itemantworten von 9884 Schülerinnen und Schülern im Multiple-Matrix-Design mit Gruppierungsmerkmal.
idstud
Schüleridentifikator. AHS
Besuch einer allgemeinbildenden höheren Schulen ( AHS
= 1), bzw. allgemeinbildenden Pflichtschule (AHS
= 0).E8RS*
dichotom bewertete Itemantworten zu Items E8RS01661
bisE8RS79931
.'data.frame': 9884 obs. of 52 variables: $ idstud : int [1:9884] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ AHS : int [1:9884] 0 0 0 0 0 0 0 0 0 0 ... $ E8RS01661: int [1:9884] 0 NA 1 NA 0 0 NA 1 NA 0 ... $ E8RS02011: int [1:9884] 0 NA 0 NA 0 0 NA 0 NA 0 ... $ E8RS02201: int [1:9884] NA 1 NA 1 NA NA 1 NA 1 NA ... [...] $ E8RS79641: int [1:9884] NA 0 0 0 0 0 NA NA 0 NA ... $ E8RS79931: int [1:9884] 0 NA NA NA NA NA 0 1 NA 0 ...
-
dat.th1: Teildatensatz mit Itemantworten der Subgruppe von 1636 Schülerinnen und Schülern, die das erste Testheft (vgl.
ibank
) bearbeitet haben.idstud
Schüleridentifikator. AHS
Besuch einer allgemeinbildenden höheren Schulen ( AHS
= 1), bzw. allgemeinbildenden Pflichtschule (AHS
= 0).E8RS*
dichotom bewertete Itemantworten zu Items E8RS01661
bisE8RS79931
.'data.frame': 1636 obs. of 27 variables: $ idstud : int [1:1636] 10010109 10010111 10020101 10020113 10020114 10030110 ... $ AHS : int [1:1636] 0 0 0 0 0 0 0 0 0 0 ... $ E8RS01661: int [1:1636] 1 0 0 1 0 1 0 0 0 0 ... $ E8RS02011: int [1:1636] 0 0 0 1 0 0 1 0 0 1 ... $ E8RS02421: int [1:1636] 0 0 0 0 0 1 0 0 0 1 ... [...] $ E8RS28551: int [1:1636] 1 0 1 0 0 0 1 1 0 0 ... $ E8RS79931: int [1:1636] 1 0 0 0 0 0 0 0 0 1 ...
-
ibank: Beispielhafte Itembank mit klassifizierenden Item-Informationen (vgl. Kapitel 1, Testkonstruktion, im Band).
task
Itemname. format
Antwortformat des Items. focus
Fokuskategorie des Items. itemnr
Itemidentifikator. 'data.frame': 50 obs. of 4 variables: $ task : chr "E8RS01661" "E8RS02011" "E8RS02201" "E8RS02231" ... $ format : chr "MC4" "MC4" "MC4" "MC4" ... $ focus : int 0 0 0 0 0 0 0 0 0 0 ... $ itemnr : int 1661 2011 2201 2231 2251 2421 2461 2891 2931 3131 ...
References
Trendtel, M., Schwabe, F. & Fellinger, R. (2016). Differenzielles Itemfunktionieren in Subgruppen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 111–147). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 4
.
Illustrationsdaten zu Kapitel 5, Testdesign
Description
Hier befindet sich die Dokumentation der in Kapitel 5, Testdesign, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel05)
Format
datenKapitel05
ist eine Liste mit den sechs Elementen tdItembank
,
tdBib2d
, tdBibPaare
, tdExItembank
, tdExBib2d
und
tdExBibPaare
, die sowohl für die Umsetzung im Kapitel als auch für die
Übungsaufgaben die relevanten Informationen auf Itemebene in Form einer
Itembank und Zwischenergebnisse aus dem Blockdesign für die Weiterverarbeitung
beinhalten.
-
tdItembank: Itembank für den Testdesignprozess, bestehend aus 286 dichotomen und polytomen Items.
testlet
Testletname des Items (gleichbedeutend mit zugewiesenem Stimulus). itemnr
Itemidentifikator task
Itemname. format
Antwortformat. focus
Fokuskategorie des Items. focus.label
Bezeichnung des Fokus. topic
Themengruppe des Inhalts des zum Item gehörenden Stimulus. audiolength
Länge der Tonaufnahme in Sekunden. RelFreq
Item-Schwierigkeit (genauer: aus Pilotierung gewonnener Erwartungswert gewichtet mit höchstem erreichbaren Punktewert bei dem Item; vgl. Kapitel 1, Testkonstruktion, im Band). rpb.WLE
Item-Trennschärfe (genauer: Punktbiseriale Korrelation der Itemantworten mit dem Weighted Likelihood Personenschätzer (WLE); vgl. Kapitel 1 und Kapitel 6, Skalierung und Linking, im Band). uniformDIF
Uniformes Differenzielles Itemfunktionieren (vgl. Kapitel 4, Differenzielles Itemfunktionieren in Subgruppen, im Band). DIF.ETS
Klassifikation des uniform DIF nach ETS (vgl. Kapitel 4 im Band). IIF_380
Wert der Fisher-Iteminformationsfunktionen am Skalenwert 380 (vgl. Kapitel 6 im Band). IIF_580
Wert der Fisher-Iteminformationsfunktionen am Skalenwert 580. 'data.frame': 286 obs. of 14 variables: $ testlet : chr [1:286] "E8LS0127" "E8LS0128" "E8LS0132" "E8LS0135" ... $ itemnr : int [1:286] 127 128 132 135 139 141 142 144 145 147 ... $ task : chr [1:286] "E8LS0127" "E8LS0128" "E8LS0132" "E8LS0135" ... $ format : chr [1:286] "MC4" "MC4" "MC4" "MC4" ... $ focus : int [1:286] 0 2 2 5 2 5 2 4 2 5 ... $ focus.label: chr [1:286] "LFocus0" "LFocus2" "LFocus2" "LFocus5" ... $ topic : chr [1:286] "Körper und Gesundheit" "Gedanken, Empfindungen und Gefühle" ... $ audiolength: int [1:286] 47 46 39 62 51 30 44 28 50 23 ... $ RelFreq : num [1:286] 0.71 0.314 0.253 0.847 0.244 ... $ rpb.WLE : num [1:286] 0.516 0.469 0.285 0.54 0.352 ... $ uniformDIF : num [1:286] 0.115726 0.474025 0.11837 0.083657 -0.000051 ... $ DIF.ETS : chr [1:286] "A+" "B+" "A+" "A+" ... $ IIF_380 : num [1:286] 0.4073 0.1542 0.0708 0.4969 0.0611 ... $ IIF_580 : num [1:286] 0.157 0.508 0.277 0.26 0.148 ...
-
tdBib2d: Vollständiges durch den BIB-Design-Algorithmus erzeugtes Itemblock-Design (vgl. Tabelle 5.3) in tabellarischer Aufstellung mit 30 Testheften (Zeilen), 6 Positionen (Spalten) und 30 Itemblöcken (Zelleneinträge).
'data.frame': 30 obs. of 6 variables: $ V1: int [1:30] 12 5 6 7 3 1 17 4 18 13 ... $ V2: int [1:30] 2 11 9 4 10 8 15 17 7 26 ... $ V3: int [1:30] 7 6 10 12 1 5 20 15 17 8 ... $ V4: int [1:30] 11 9 3 2 8 4 13 5 22 7 ... $ V5: int [1:30] 10 7 2 9 4 12 6 18 13 1 ... $ V6: int [1:30] 3 8 1 5 6 11 16 27 14 24 ...
-
tdBibPaare: Ergebnis des BIB-Design-Algorithmus als Blockpaare, wobei die Zelleneinträge die paarweisen Auftretenshäufigkeiten des Zeilenblocks mit dem Spaltenblock im Design anzeigen.
'data.frame': 30 obs. of 30 variables: $ V1 : int [1:30] 6 1 2 2 1 2 1 3 1 2 ... $ V2 : int [1:30] 1 6 2 2 1 1 3 0 3 2 ... $ V3 : int [1:30] 2 2 6 1 0 3 1 2 2 5 ... [...] $ V29: int [1:30] 0 0 1 1 0 1 0 0 1 2 ... $ V30: int [1:30] 1 1 1 0 0 0 0 1 0 1 ...
-
tdExItembank: Beispiel-Itembank für den Testdesignprozess in den Übungsaufgaben zum Kapitel.
task
Itemname. format
Antwortformat. focus
Fokuskategorie des Items. p
Item-Leichtigkeit (genauer: in der Pilotierung beobachtete relative Lösungshäufigkeit für dichotome Items). p_cat
Dreistufige Kategorisierung der Schwierigkeit. itemdiff
Rasch-kalibrierte Itemparameter. bearbeitungszeit
Geschätzte mittlere Bearbeitungszeit des Items. 'data.frame': 250 obs. of 7 variables: $ task : chr [1:250] "M80003" "M80004" "M80006" "M80007" ... $ format : chr [1:250] "ho" "MC4" "MC4" "ho" ... $ focus : int [1:250] 1 4 4 2 3 4 1 2 3 3 ... $ p : num [1:250] 0.84 0.56 0.34 0.45 0.2 0.42 0.77 0.42 0.34 0.71 ... $ p_cat : chr [1:250] "leicht" "mittel" "mittel" "mittel" ... $ itemdiff : int [1:250] 404 570 676 622 761 636 457 636 676 494 ... $ bearbeitungszeit: int [1:250] 90 60 90 120 90 150 90 30 120 90 ...
-
tdExBib2d: Vollständiges Itemblock-Design zur Weiterverarbeitung in den Übungsaufgaben zum Kapitel in tabellarischer Aufstellung mit 10 Testheften (Zeilen), 4 Positionen (Spalten) und 10 Itemblöcken (Zelleneinträge).
'data.frame': 10 obs. of 4 variables: $ V1: int [1:10] 1 9 8 2 10 4 7 3 5 6 $ V2: int [1:10] 10 6 7 8 4 1 9 5 3 2 $ V3: int [1:10] 6 10 9 1 5 2 3 8 4 7 $ V4: int [1:10] 7 8 4 3 9 6 1 10 2 5
-
tdExBibPaare: Itemblock-Design zur Weiterverarbeitung in den Übungsaufgaben in der Darstellung als Blockpaare, wobei die Zelleneinträge die paarweisen Auftretenshäufigkeiten des Zeilenblocks mit dem Spaltenblock im Design anzeigen.
'data.frame': 10 obs. of 10 variables: $ V1 : int [1:10] 4 2 2 1 0 2 2 1 1 1 $ V2 : int [1:10] 2 4 2 2 2 2 1 1 0 0 $ V3 : int [1:10] 2 2 4 1 2 0 1 2 1 1 $ V4 : int [1:10] 1 2 1 4 2 1 1 1 2 1 $ V5 : int [1:10] 0 2 2 2 4 1 1 1 1 2 $ V6 : int [1:10] 2 2 0 1 1 4 2 1 1 2 $ V7 : int [1:10] 2 1 1 1 1 2 4 1 2 1 $ V8 : int [1:10] 1 1 2 1 1 1 1 4 2 2 $ V9 : int [1:10] 1 0 1 2 1 1 2 2 4 2 $ V10: int [1:10] 1 0 1 1 2 2 1 2 2 4
References
Kiefer, T., Kuhn, J.-T. & Fellinger, R. (2016). Testdesign. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 149–184). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 5
.
Illustrationsdaten zu Kapitel 6, Skalierung und Linking
Description
Hier befindet sich die Dokumentation der in Kapitel 6, Skalierung und Linking, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel06)
Format
datenKapitel06
ist eine Liste mit den fünf Elementen dat
,
itembank
, datTH1
, itembankTH1
und normdat
.
-
dat: Dichotome und polytome Itemantworten von 9885 Schülerinnen und Schülern im Multiple-Matrix-Design mit Stichprobengewichten und Testheftinformation.
index
Laufindex. idstud
Schüleridentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2, Stichprobenziehung, im Band). th
Bearbeitetes Testheft. I1...I50
Itemantworten. 'data.frame': 9885 obs. of 54 variables: $ index : int [1:9885] 1 2 3 4 5 6 7 8 9 10 ... $ idstud : int [1:9885] 10010101 10010102 10010103 10010105 10010106 10010107 10010108 ... $ wgtstud: num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... $ th : chr [1:9885] "ER04" "ER03" "ER05" "ER02" ... $ I1 : int [1:9885] 0 NA 1 NA 0 0 NA 1 NA 0 ... $ I2 : int [1:9885] 0 NA 0 NA 0 0 NA 0 NA 0 ... $ I3 : int [1:9885] NA 1 NA 1 NA NA 1 NA 1 NA ... [...] $ I49 : int [1:9885] 0 NA NA 4 NA NA 3 NA 3 NA ... $ I50 : int [1:9885] NA 0 0 NA 1 2 NA 0 NA 2 ...
-
itembank: Den Instrumentendaten zugrundeliegende Itembank mit klassifizierenden Item-Informationen (vgl. Kapitel 1, Testkonstruktion, im Band).
Item
Itemname. format
Antwortformat des Items. focus
Fokuskategorie des Items. itemnr
Itemidentifikator. N.subI
Anzahl Subitems. 'data.frame': 50 obs. of 5 variables: $ index : int [1:50] 1 2 3 4 5 6 7 8 9 10 ... $ Item : chr [1:50] "I1" "I2" "I3" "I4" ... $ format : chr [1:50] "MC4" "MC4" "MC4" "MC4" ... $ focus : int [1:50] 0 0 0 0 0 0 0 0 0 0 ... $ itemnr : int [1:50] 1661 2011 2201 2231 2251 2421 2461 2891 2931 3131 ... $ N.subI : int [1:50] 1 1 1 1 1 1 1 1 1 1 ...
-
datTH1: Teildatensatz mit Itemantworten der Subgruppe von 1637 Schülerinnen und Schülern, die das erste Testheft bearbeitet haben.
index
Laufindex. idstud
Schüleridentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2, Stichprobenziehung, im Band). th
Bearbeitetes Testheft. I1...I50
Itemantworten. 'data.frame': 1637 obs. of 29 variables: $ index : int [1:1637] 8 10 12 23 24 34 41 46 54 57 ... $ idstud : int [1:1637] 10010109 10010111 10020101 10020113 10020114 10030110 10040103 ... $ wgtstud: num [1:1637] 34.5 34.5 29.2 29.2 29.2 ... $ th : chr [1:1637] "ER01" "ER01" "ER01" "ER01" ... $ I1 : int [1:1637] 1 0 0 1 0 1 0 0 0 0 ... $ I2 : int [1:1637] 0 0 0 1 0 0 1 0 0 1 ... $ I6 : int [1:1637] 0 0 0 0 0 1 0 0 0 1 ... [...] $ I47 : int [1:1637] 0 2 0 2 0 0 2 1 0 1 ... $ I50 : int [1:1637] 0 2 0 2 0 0 1 1 0 1 ...
-
itembankTH1: Itembank zum Testheft 1.
Item
Itemname. format
Antwortformat des Items. focus
Fokuskategorie des Items. itemnr
Itemidentifikator. N.subI
Anzahl Subitems. 'data.frame': 25 obs. of 5 variables: $ Item : chr [1:25] "I1" "I2" "I6" "I9" ... $ format : chr [1:25] "MC4" "MC4" "MC4" "MC4" ... $ focus : int [1:25] 0 0 0 0 0 1 1 1 1 1 ... $ itemnr : int [1:25] 1661 2011 2421 2931 3131 3641 4491 4681 5621 5761 ... $ N.subI : int [1:25] 1 1 1 1 1 1 1 1 1 1 ...
-
normdat: Instrumentendaten einer Normierungsstudie (vgl. Kapitel 3, Standard-Setting, und Kapitel 5, Testdesign, im Band) mit Ankeritems für die Illustration von Linkingmethoden.
idstud
Schüleridentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers in der Normierungsstudie (es wird von einer vollständig randomisierten Stichprobe ausgegangen, weshalb die Gewichte konstant 1 sind). th
Testheft. I*
Itemantworten zu Items, die in der zu linkenden Studie auch eingesetzt werden. J*
Itemantworten zu Items, die in der zu linkenden Studie nicht verwendet werden. 'data.frame': 3000 obs. of 327 variables: $ idstud : int [1:3000] 1000 1005 1011 1014 1021 1024 1025 1026 1027 1028 ... $ wgtstud: int [1:3000] 1 1 1 1 1 1 1 1 1 1 ... $ th : chr [1:3000] "E8R01" "E8R02" "E8R03" "E8R04" ... $ J1 : int [1:3000] NA NA NA NA NA NA NA NA 0 NA ... $ J2 : int [1:3000] NA NA 0 NA NA NA NA NA NA NA ... $ J3 : int [1:3000] NA NA NA NA NA NA NA NA 0 NA ... [...] $ I39 : int [1:3000] NA NA NA NA NA NA NA NA NA NA ... $ I40 : int [1:3000] NA NA NA NA NA NA NA NA 0 NA ...
References
Trendtel, M., Pham, G. & Yanagida, T. (2016). Skalierung und Linking. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 185–224). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 6
.
Illustrationsdaten zu Kapitel 7, Statistische Analysen produktiver Kompetenzen
Description
Hier befindet sich die Dokumentation der in Kapitel 7, Statistische Analysen produktiver Kompetenzen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel07)
Format
datenKapitel07
ist eine Liste mit den fünf Elementen prodRat
,
prodPRat
, prodRatL
, prodRatEx
und prodRatLEx
,
zu unterschiedlichen Darstellungen von Ratings zu Schreib-Performanzen für
das Kapitel wie auch die darin gestellten Übungsaufgaben.
-
prodRat: Bewertung der Texte von 9736 Schülerinnen und Schülern zu einer von 3 "long prompts" durch einen (oder mehrere) der 41 Raters.
idstud
Schüleridentifikator. aufgabe
3 lange Schreibaufgaben. rater
41 Raters. TA
Bewertung des Schülertexts auf der Dimension Task Achievement anhand einer 8-stufigen Ratingskala. CC
Bewertung des Schülertexts auf der Dimension Coherence and Cohesion anhand einer 8-stufigen Ratingskala. GR
Bewertung des Schülertexts auf der Dimension Grammar anhand einer 8-stufigen Ratingskala. VO
Bewertung des Schülertexts auf der Dimension Vocabulary anhand einer 8-stufigen Ratingskala. 'data.frame': 10755 obs. of 7 variables: $ idstud : int [1:10755] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ aufgabe: chr [1:10755] "E8W014" "E8W014" "E8W014" "E8W014" ... $ rater : chr [1:10755] "R141" "R143" "R191" "R191" ... $ TA : int [1:10755] 0 0 0 3 4 4 0 0 2 4 ... $ CC : int [1:10755] 0 0 0 3 5 2 0 0 1 3 ... $ GR : int [1:10755] 0 0 0 3 5 3 0 0 1 4 ... $ VO : int [1:10755] 0 0 0 3 5 2 0 0 1 3 ...
-
prodPRat: Bewertung der Schülertexte von 841 Schülerinnen und Schülern durch Pseudoraters.
Die Mehrfachkodierungen der Schülertexte werden auf zwei zufällige Raters reduziert (siehe Unterabschnitt 7.1 für eine Erläuterung).idstud
Schüleridentifikator. aufgabe
3 lange Schreibaufgaben. TA_R1...VO_R1
Bewertung des Schülertexts auf den Dimension Task Achievement ( TA_*
), Coherence and Cohesion (CC_*
), Grammar (GR_*
) und Vocabulary (VO_*
) anhand einer 8-stufigen Ratingskala durch Pseudorater/in 1.TA_R2...VO_R2
Bewertung des Schülertexts auf den Dimension Task Achievement ( TA_*
), Coherence and Cohesion (CC_*
), Grammar (GR_*
) und Vocabulary (VO_*
) anhand einer 8-stufigen Ratingskala durch Pseudorater/in 2.'data.frame': 841 obs. of 10 variables: $ idstud : int [1:841] 10010108 10010112 10030106 10030110 10030112 10050105 ... $ aufgabe: chr [1:841] "E8W006" "E8W006" "E8W010" "E8W006" ... $ TA_R1 : int [1:841] 0 1 5 2 4 6 2 4 0 5 ... $ CC_R1 : int [1:841] 0 1 5 2 6 5 2 6 0 3 ... $ GR_R1 : int [1:841] 0 0 5 1 5 5 2 6 0 1 ... $ VO_R1 : int [1:841] 0 2 4 1 5 5 3 6 0 2 ... $ TA_R2 : int [1:841] 0 0 3 4 4 6 5 2 0 5 ... $ CC_R2 : int [1:841] 0 0 2 2 4 5 2 3 0 2 ... $ GR_R2 : int [1:841] 0 0 2 1 5 5 3 4 0 2 ... $ VO_R2 : int [1:841] 0 0 3 2 5 6 4 3 0 2 ...
-
prodRatL: Bewertung der Schülertexte im Long Format.
idstud
Schüleridentifikator. aufgabe
3 lange Schreibaufgaben. rater
41 Raters. item
Dimension. response
Rating zur Aufgabe in jeweiliger Dimension. 'data.frame': 43020 obs. of 5 variables: $ idstud : int [1:43020] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ aufgabe : chr [1:43020] "E8W014" "E8W014" "E8W014" "E8W014" ... $ rater : chr [1:43020] "R141" "R143" "R191" "R191" ... $ item : Factor w/ 4 levels "TA","CC","GR",..: 1 1 1 1 1 1 1 1 1 1 ... $ response: int [1:43020] 0 0 0 3 4 4 0 0 2 4 ...
-
prodRatEx: Übungsdatensatz: Bewertung der Texte von 9748 Schülerinnen und Schülern zu einer von 3 "short prompts" durch einen (oder mehrere) der 41 Raters.
idstud
Schüleridentifikator. aufgabe
3 Schreibaufgaben. rater
41 Raters. TA
Bewertung des Schülertexts auf der Dimension Task Achievement anhand einer 8-stufigen Ratingskala. CC
Bewertung des Schülertexts auf der Dimension Coherence and Cohesion anhand einer 8-stufigen Ratingskala. GR
Bewertung des Schülertexts auf der Dimension Grammar anhand einer 8-stufigen Ratingskala. VO
Bewertung des Schülertexts auf der Dimension Vocabulary anhand einer 8-stufigen Ratingskala. 'data.frame': 10643 obs. of 7 variables: $ idstud : int [1:10643] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ aufgabe: chr [1:10643] "E8W001" "E8W011" "E8W001" "E8W011" ... $ rater : chr [1:10643] "R123" "R132" "R132" "R113" ... $ TA : int [1:10643] 0 3 0 4 3 2 0 1 1 5 ... $ CC : int [1:10643] 0 3 0 4 2 2 0 1 2 3 ... $ GR : int [1:10643] 0 3 0 4 3 1 0 1 3 1 ... $ VO : int [1:10643] 0 3 0 4 3 2 0 1 3 1 ...
-
prodRatLEx: Übungsdatensatz: Bewertung der Schülertexte im Long Format.
idstud
Schüleridentifikator. aufgabe
3 kurze Schreibaufgaben. rater
41 Raters. item
Dimension. response
Rating zur Aufgabe in jeweiliger Dimension. 'data.frame': 42572 obs. of 5 variables: $ idstud : int [1:42572] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ aufgabe : chr [1:42572] "E8W001" "E8W011" "E8W001" "E8W011" ... $ rater : chr [1:42572] "R123" "R132" "R132" "R113" ... $ item : Factor w/ 4 levels "TA","CC","GR",..: 1 1 1 1 1 1 1 1 1 1 ... $ response: int [1:42572] 0 3 0 4 3 2 0 1 1 5 ...
References
Freunberger, R., Robitzsch, A. & Luger-Bazinger, C. (2016). Statistische Analysen produktiver Kompetenzen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 225–258). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 7
.
Illustrationsdaten zu Kapitel 8, Fehlende Daten und Plausible Values
Description
Hier befindet sich die Dokumentation der in Kapitel 8, Fehlende Daten und Plausible Values, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel08)
Format
datenKapitel08
ist eine Liste mit den vier Elementen data08H
,
data08I
, data08J
und data08K
, die Kontextinformationen mit
fehlenden Daten zur Imputation sowie Instrumentendaten im Multiple-Matrix-Design
für die Plausible-Value-Ziehung enthalten.
-
data08H: Roh-Datensatz mit Leistungsschätzern und Kontextinformationen für 2507 Schüler/innen in 74 Schulen.
idstud
Schüleridentifikator. idschool
Schulenidentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2, Stichprobenziehung, im Band). wgtstud
Stichprobengewicht der Schule (vgl. Kapitel 2 im Band). Stratum
Stratum der Schule. ( 1:4
= Stratum 1 bis Stratum 4; für eine genauere Beschreibung der Strata, siehe Kapitel 2 im Band).female
Geschlecht ( 1
= weiblich,0
= männlich).migrant
Migrationsstatus ( 1
= mit Migrationshintergrund,0
= ohne Migrationshintergrund).HISEI
Sozialstatus (vgl. Kapitel 10, Reporting und Analysen, im Band). eltausb
Ausbildung der Eltern. buch
Anzahl der Bücher zu Hause. SK
Fragebogenskala "Selbstkonzept". LF
Fragebogenskala "Lernfreude". NSchueler
Anzahl Schüler/innen in der 4. Schulstufe (vgl. Kapitel 2 im Band). NKlassen
Anzahl Klassen in der 4. Schulstufe (vgl. Kapitel 2 im Band). SES_Schule
Auf Schulebene erfasster Sozialstatus (siehe Buchkapitel). E8WWLE
WLE der Schreibkompetenz (vgl. Kapitel 7, Statistische Analysen produktiver Kompetenzen, im Band). E8LWLE
WLE der Hörverstehenskompetenz (vgl. Kapitel 6, Skalierung und Linking, im Band). 'data.frame': 2507 obs. of 17 variables: $ idstud : int [1:2507] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ idschool : int [1:2507] 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 ... $ wgtstud : num [1:2507] 34.5 34.5 34.5 34.5 34.5 ... $ wgtschool : num [1:2507] 31.2 31.2 31.2 31.2 31.2 ... $ stratum : int [1:2507] 1 1 1 1 1 1 1 1 1 1 ... $ female : int [1:2507] 0 0 0 0 1 0 1 1 1 1 ... $ migrant : int [1:2507] 0 0 0 0 0 NA 0 0 0 0 ... $ HISEI : int [1:2507] 31 NA 25 27 27 NA NA 57 52 58 ... $ eltausb : int [1:2507] 2 NA 2 2 2 NA 2 1 2 1 ... $ buch : int [1:2507] 1 1 1 1 3 NA 4 2 5 4 ... $ SK : num [1:2507] 2.25 2.25 3 3 2.5 NA 2.5 3.25 3.5 2.5 ... $ LF : num [1:2507] 1.25 1.5 1 1 4 NA 2 3.5 3.75 2.25 ... $ NSchueler : int [1:2507] 69 69 69 69 69 69 69 69 69 69 ... $ NKlassen : int [1:2507] 1 1 1 1 1 1 1 1 1 1 ... $ SES_Schule: num [1:2507] 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 ... $ E8WWLE : num [1:2507] -3.311 -0.75 -3.311 0.769 1.006 ... $ E8LWLE : num [1:2507] -1.175 -1.731 -1.311 0.284 0.336 ...
-
data08I: Datensatz zur Illustration der Bedeutung einer geeigneten Behandlung fehlender Werte und von Messfehlern.
index
Laufindex. x
Vollständig beobachteter Sozialstatus. theta
Kompetenzwert. WLE
WLE-Personenschätzer (vgl. Kapitel 6 im Band). SEWLE
Messfehler ("standard error") des WLE-Personenschätzers. X
Sozialstatus mit teilweise fehlenden Werten. 'data.frame': 1500 obs. of 6 variables: $ index: int [1:1500] 1 2 3 4 5 6 7 8 9 10 ... $ x : num [1:1500] 0.69 0.15 -0.13 -0.02 0.02 0.02 -0.56 0.14 -0.06 -1.41 ... $ theta: num [1:1500] 2.08 -1.56 -0.65 -0.62 0.76 -1 1.12 0.08 0 -0.6 ... $ WLE : num [1:1500] 1.22 -2.9 -2.02 0.03 0.8 0.93 0.28 -0.77 -0.31 -1.76 ... $ SEWLE: num [1:1500] 0.83 0.82 0.8 0.8 0.8 0.81 0.81 0.8 0.8 0.8 ... $ X : num [1:1500] 0.69 0.15 NA NA 0.02 0.02 -0.56 NA -0.06 -1.41 ...
-
data08J: Datensatz data08H nach Imputation der fehlenden Werte. Für die Beschreibung der Variablen, siehe
data08H
.'data.frame': 2507 obs. of 14 variables: $ idstud : int [1:2507] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ wgtstud : num [1:2507] 34.5 34.5 34.5 34.5 34.5 ... $ female : int [1:2507] 0 0 0 0 1 0 1 1 1 1 ... $ migrant : num [1:2507] 0 0 0 0 0 ... $ HISEI : num [1:2507] 31 56.8 25 27 27 ... $ eltausb : num [1:2507] 2 1.04 2 2 2 ... $ buch : num [1:2507] 1 1 1 1 3 ... $ SK : num [1:2507] 2.25 2.25 3 3 2.5 ... $ LF : num [1:2507] 1.25 1.5 1 1 4 ... $ E8LWLE : num [1:2507] -1.175 -1.731 -1.311 0.284 0.336 ... $ E8WWLE : num [1:2507] -3.311 -0.75 -3.311 0.769 1.006 ... $ NSchueler : num [1:2507] 69 69 69 69 69 69 69 69 69 69 ... $ NKlassen : int [1:2507] 1 1 1 1 1 1 1 1 1 1 ... $ SES_Schule: num [1:2507] 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 0.57 ...
-
data08K: Datensatz mit Itemantworten der Schüler/innen zu den Testinstrumenten zu Hörverstehen und Schreiben.
idstud
Schüleridentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2 im Band). E8LS*
Itemantworten für Hörverstehen (vgl. Kapitel 6). E8W*
Itemantworten für Schreiben (vgl. Kapitel 7). 'data.frame': 2507 obs. of 99 variables: $ idstud : int [1:2507] 10010101 10010102 10010103 10010105 10010106 10010107 ... $ wgtstud : num [1:2507] 34.5 34.5 34.5 34.5 34.5 ... $ E8LS0158 : int [1:2507] NA NA NA NA NA NA 0 0 NA NA ... $ E8LS0165 : int [1:2507] 0 1 1 0 1 0 NA NA 1 0 ... $ E8LS0166 : int [1:2507] 0 0 1 1 0 1 NA NA 1 1 ... [...] $ E8W014CC : int [1:2507] 0 0 0 3 5 2 NA NA NA NA ... $ E8W014GR : int [1:2507] 0 0 0 3 5 3 NA NA NA NA ... $ E8W014VOC: int [1:2507] 0 0 0 3 5 2 NA NA NA NA ...
References
Robitzsch, A., Pham, G. & Yanagida, T. (2016). Fehlende Daten und Plausible Values. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 259–293). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 8
.
Illustrationsdaten zu Kapitel 9, Fairer Vergleich in der Rueckmeldung
Description
Hier befindet sich die Dokumentation der in Kapitel 9, Fairer Vergleich in der Rückmeldung, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel09)
Format
datenKapitel09
ist ein singulärer vollständiger Datensatz.
-
datenKapitel09: Datensatz mit sieben Kontextinformationen und 43 im Fairen Vergleich daraus abgeleiteten und berechneten Kenngrößen zu 244 Schulen (
Kapitel 9
).idschool
Schulenidentifikator. Stratum
Stratum der Schule. ( 1:4
= Stratum 1 bis Stratum 4; für eine genauere Beschreibung der Strata, siehe Kapitel 2, Stichprobenziehung, im Band).groesse
Logarithmierte Schulgröße. TWLE
Aggregierte Leistungsschätzer der Schüler in der Schule (abhängige Variable im Fairen Verlgeich). female
Anteil an Mädchen in der Schule. mig
Anteil an Schülerinnen und Schülern mit Migrationshintergrund. sozstat
Mittlerer sozioökonomischer Status (SES). zgroesse...zsozzsoz
z-Standardisierte Werte der entsprechenden Variablen und Interaktionen. expTWLE.*
Nach den jeweiligen Modellen erwartete (aggregierte) Leistungswerte der Schulen unter Berücksichtigung des Schulkontexts. *.eb*
Untere und obere Grenzen der Erwartungsbereiche (EB) der Schulen und Indikator der Lage der Schule zum Bereich ( -1
= unter dem EB,0
= im EB,1
= über dem EB).'data.frame': 244 obs. of 50 variables: $ idschool : int 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 ... $ stratum : int 1 1 1 1 1 1 1 1 1 1 ... $ groesse : num 2.48 2.64 2.71 2.83 2.89 ... $ TWLE : num 449 447 495 482 514 ... $ female : num 0.545 0.462 0.571 0.529 0.389 ... $ mig : num 0.0168 0.0769 0 0 0 ... $ sozstat : num -1.034 -0.298 -0.413 -0.259 -0.197 ... $ zgroesse : num -2.86 -2.54 -2.4 -2.14 -2.02 ... [...] $ expTWLE.OLS1 : num 431 475 481 489 485 ... $ expTWLE.OLS2 : num 439 463 483 490 471 ... $ expTWLE.Lasso1 : num 430 472 475 484 482 ... $ expTWLE.Lasso2 : num 434 470 481 486 476 ... [...] $ expTWLE.np : num 422 478 479 490 465 ... [...] $ OLS1.eblow31 : num 415 460 465 474 470 ... $ OLS1.ebupp31 : num 446 491 496 505 501 ... $ OLS1.pos.eb31 : int 1 -1 0 0 1 -1 -1 -1 0 0 ... [...]
References
Pham, G., Robitzsch, A., George, A. C. & Freunberger, R. (2016). Fairer Vergleich in der Rückmeldung. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 295–332). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 9
.
Illustrationsdaten zu Kapitel 10, Reporting und Analysen
Description
Hier befindet sich die Dokumentation der in Kapitel 10, Reporting und Analysen, im Herausgeberband Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung, verwendeten Daten. Die Komponenten der Datensätze werden knapp erläutert und deren Strukturen dargestellt.
Usage
data(datenKapitel10)
Format
datenKapitel10
ist eine Liste mit den vier Elementen,
dat
, dat.roh
, dat.schule
und dat.schule.roh
.
Die Elemente dat
und dat.schule
enthalten jeweils zehn imputierte
Datensätze (vgl. Kapitel 8, Fehlende Daten und Plausible Values, im
Band). Zum Vergleich stehen denen die Rohdatensätze dat.roh
bzw.
dat.schule.roh
gegenüber.
-
dat und dat.roh: Roh-Datensatz bzw. Liste mit zehn imputierten Datensätzen für 9885 Schülerinnen und Schüler.
idschool
Schulenidentifikator. idstud
Schüleridentifikator. idclass
Klassenidentifikator. wgtstud
Stichprobengewicht der Schülerin/des Schülers (vgl. Kapitel 2, Stichprobenziehung, im Band). female
Geschlecht ( 1
= weiblich,0
= männlich).migrant
Migrationsstatus ( 1
= mit Migrationshintergrund,0
= ohne Migrationshintergrund).HISEI
Sozialstatus (vgl. Kapitel 10, Reporting und Analysen, im Band). eltausb
Ausbildung der Eltern. buch
Anzahl der Bücher zu Hause. SK
Fragebogenskala "Selbstkonzept". LF
Fragebogenskala "Lernfreude". E8RTWLE
WLE der Lesekompetenz (vgl. Kapitel 1, Testkonstruktion, und Kapitel 6, Skalierung und Linking, im Band). E8RPV
Plausible Values für die Leistung in Englisch Lesen (vgl. Kapitel 8 im Band). jkzone
Jackknife-Zone im Jackknife-Repeated-Replication-Design (vgl. Kapitel 2). jkrep
Jackknife-Replikationsfaktor im Jackknife-Repeated-Replication-Design (vgl. Kapitel 2). w_fstr*
Jackknife-Replikationsgewichte (vgl. Kapitel 2). List of 10 $ :'data.frame': 9885 obs. of 151 variables: ..$ idschool : int [1:9885] 1001 1001 1001 1001 1001 1001 1001 ... ..$ idstud : int [1:9885] 10010101 10010102 10010103 10010105 ... ..$ idclass : int [1:9885] 100101 100101 100101 100101 100101 ... ..$ wgtstud : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... ..$ female : int [1:9885] 0 0 0 0 1 0 1 1 1 1 ... ..$ migrant : int [1:9885] 0 0 0 0 0 0 0 0 0 0 ... ..$ HISEI : int [1:9885] 31 28 25 27 27 76 23 57 52 58 ... ..$ eltausb : int [1:9885] 2 1 2 2 2 2 2 1 2 1 ... ..$ buch : int [1:9885] 1 1 1 1 3 3 4 2 5 4 ... ..$ SK : num [1:9885] 2.25 2.25 3 3 2.5 3.25 2.5 3.25 3.5 2.5 ... ..$ LF : num [1:9885] 1.25 1.5 1 1 4 3 2 3.5 3.75 2.25 ... ..$ E8RTWLE : num [1:9885] 350 438 383 613 526 ... ..$ E8RPV : num [1:9885] 390 473 380 599 509 ... ..$ jkzone : int [1:9885] 37 37 37 37 37 37 37 37 37 37 ... ..$ jkrep : int [1:9885] 0 0 0 0 0 0 0 0 0 0 ... ..$ w_fstr1 : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... ..$ w_fstr2 : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... ..$ w_fstr3 : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... [...] ..$ w_fstr83 : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... ..$ w_fstr84 : num [1:9885] 34.5 34.5 34.5 34.5 34.5 ... $ :'data.frame': 9885 obs. of 151 variables: [...]
-
dat.schule und dat.schule.roh: Roh-Datensatz bzw. Liste mit zehn imputierten Datensätzen als Liste für 244 Schulen. Es handelt sich hierbei – wie bei allen Datensätzen im Band – um fiktive (höchstens partiell-synthetische) Daten!
idschool
Schulenidentifikator. Schultyp
Schultyp ( AHS
= allgemeinbildende höhere Schule, bzw.APS
= allgemeinbildende Pflichtschule).Strata
Stratum der Schule. ( 1:4
= Stratum 1 bis Stratum 4, für eine genauere Beschreibung der Strata; siehe Kapitel 2 im Band).Strata.label
Bezeichnung des Stratums. NSchueler
Anzahl Schüler/innen in der 4. Schulstufe (vgl. Kapitel 2 im Band). NKlassen
Anzahl Klassen in der 4. Schulstufe (vgl. Kapitel 2 im Band). gemgroesse
Gemeindegröße. SCFRA04x02
Fragebogenvariable aus Schulleiterfragebogen zur Schulgröße (vgl. https://www.bifie.at/node/2119). SCFO05a*
Fragebogenvariable aus Schulleiterfragebogen zur "Schwerpunktschule für ..." ( *a01
= Informatik,*a02
= Mathematik,*a03
= Musik,*a04
= Naturwissenschaften,*a05
= Sport,*a06
= Sprachen,*a07
= Technik,*a081
= Anderes; vgl. https://www.bifie.at/node/2119). Es handelt sich hierbei um rein fiktive Daten!HISEI
Auf Schulenebene aggregierte HISEI. E8RPV
Auf Schulenebene aggregierte Plausible Values für die Leistung in Englisch Lesen. List of 10 $ :'data.frame': 244 obs. of 18 variables: ..$ idschool : int [1:244] 1001 1002 1003 1004 1005 1006 1007 1010 ... ..$ Schultyp : chr [1:244] "HS" "HS" "HS" "HS" ... ..$ Strata : int [1:244] 1 1 1 1 1 1 1 1 1 1 ... ..$ Strata.label: chr [1:244] "HS/Land" "HS/Land" "HS/Land" "HS/Land" ... ..$ NSchueler : int [1:244] 12 14 15 17 18 19 20 20 21 22 ... ..$ NKlassen : int [1:244] 1 1 1 1 2 1 2 1 2 2 ... ..$ gemgroesse : int [1:244] 5 4 4 5 3 4 5 4 4 5 ... ..$ SCFRA04x02 : int [1:244] 45 63 47 81 95 80 66 86 104 126 ... ..$ SCFO05a01 : int [1:244] 1 0 0 0 0 0 0 1 1 0 ... ..$ SCFO05a02 : int [1:244] 0 0 0 0 0 0 0 0 0 0 ... ..$ SCFO05a03 : int [1:244] 1 1 0 0 0 0 0 0 0 0 ... ..$ SCFO05a04 : int [1:244] 1 0 0 0 0 1 0 0 0 0 ... ..$ SCFO05a05 : int [1:244] 0 0 0 0 1 0 1 0 0 0 ... ..$ SCFO05a06 : int [1:244] 0 1 1 0 0 1 0 0 1 0 ... ..$ SCFO05a07 : int [1:244] 0 0 0 0 0 0 0 0 0 0 ... ..$ SCFO05a081 : int [1:244] 0 0 1 0 0 1 1 0 0 0 ... ..$ HISEI : num [1:244] 33.5 48.6 41.1 43.5 46.9 ... ..$ E8RPV : num [1:244] 471 463 513 494 525 ... [...]
References
Bruneforth, M., Oberwimmer, K. & Robitzsch, A. (2016). Reporting und Analysen. In S. Breit & C. Schreiner (Hrsg.), Large-Scale Assessment mit R: Methodische Grundlagen der österreichischen Bildungsstandardüberprüfung (pp. 333–362). Wien: facultas.
See Also
Für die Verwendung der Daten, siehe Kapitel 10
.