The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Flagging repeaters on raw score gain punishes candidates who studied or remediated. retestR asks a different question: is this gain larger than this candidate’s circumstances predict, and is it concentrated where preknowledge would put it?
Each repeater took two disjoint forms drawn from a calibrated bank in which
every item is marked either exposed (long-running, possibly compromised) or
new. The simulation plants preknowledge in 5% of repeaters.
library(retestR)
sim <- rt_simulate(n_persons = 800, form_exposed = 30, form_new = 15, seed = 1)
head(sim$data$persons)
#> person days_between remediation
#> 1 C00001 322 1
#> 2 C00002 354 0
#> 3 C00003 320 0
#> 4 C00004 177 0
#> 5 C00005 94 0
#> 6 C00006 58 1
table(sim$truth$preknowledge)
#>
#> FALSE TRUE
#> 758 42
With real data, assemble the same structure with rt_data(responses, persons, bank).
The growth model uses attempt 1 and only the new items of attempt 2, so preknowledge cannot inflate the expected gain.
fit <- rt_fit(sim, growth = ~ log(days_between) + remediation)
fit
#> <rt_fit> expected-gain model, 800 repeaters
#> attempt-1 ability: N(-0.513, 0.732^2)
#> growth coefficients:
#> estimate se
#> (Intercept) -0.446 0.209
#> log(days_between) 0.144 0.041
#> remediation 0.392 0.052
#> growth SD: 0.260 | log-RT residual SD: 0.502
risk <- rt_risk(fit, n_null = 4, alpha = 0.01, seed = 1)
risk
#> <rt_risk> 800 repeaters | evidence: exposed + rt | null draws: 3200
#> 44 flagged at p < 0.01 (about 8.0 expected if everyone were honest); 38 with q < 0.05
#>
#> person S1 S2 z_gain z_exposed z_rt T p_gain p_exposed p_rt p_value
#> C00737 10 25 2.760 5.71 5.77 11.49 0.001250 0.000312 0.000312 0.000312
#> C00660 3 19 3.948 6.52 4.79 11.31 0.000312 0.000312 0.000312 0.000312
#> C00257 5 25 3.981 6.68 4.50 11.19 0.000312 0.000312 0.000312 0.000312
#> C00717 11 26 2.603 3.87 6.30 10.18 0.002499 0.000312 0.000312 0.000312
#> C00055 7 18 1.645 4.61 4.35 8.96 0.049984 0.000312 0.000312 0.000312
#> C00265 13 30 3.543 5.33 3.21 8.54 0.000312 0.000312 0.000625 0.000312
#> C00651 14 27 3.200 4.15 4.37 8.52 0.000625 0.000312 0.000312 0.000312
#> C00176 15 25 0.616 2.95 5.16 8.11 0.276476 0.001250 0.000312 0.000312
#> C00012 21 34 2.129 3.13 4.89 8.02 0.014683 0.000937 0.000312 0.000312
#> C00525 25 33 1.502 2.67 5.16 7.84 0.064980 0.002812 0.000312 0.000312
#> q_value flag
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
#> 0.00893 TRUE
p_value is calibrated by simulating complete honest administrations
through the same pipeline, so it is the false-positive rate for an honest
repeater.
table(flagged = risk$flag, preknowledge = sim$truth$preknowledge)
#> preknowledge
#> flagged FALSE TRUE
#> FALSE 754 2
#> TRUE 4 40
Flag the same number of candidates by raw gain and look at who gets caught:
raw <- rt_raw_gain(sim)
k <- sum(risk$flag)
raw_flag <- raw$gain >= sort(raw$gain, decreasing = TRUE)[k]
honest_remediated <- !sim$truth$preknowledge & sim$truth$remediation == 1
c(model_caught = sum(risk$flag & sim$truth$preknowledge),
raw_caught = sum(raw_flag & sim$truth$preknowledge),
model_flags_remediated = sum(risk$flag & honest_remediated),
raw_flags_remediated = sum(raw_flag & honest_remediated))
#> model_caught raw_caught model_flags_remediated
#> 40 17 2
#> raw_flags_remediated
#> 17
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.