Introduction

Celebrating yet another birthday surrounded by my family, I was reminiscing about another birthday 70 years ago that directed me towards a life in the exact sciences. It was the hoped-for birthday present: a 12” scientific slide rule. It allowed me to do complex calculations efficiently and transparently.

At present I am similarly awed by the slide rule’s 21. century successor - R, a tool, no modern scientist should be without. In my dotage, I spend much time popularizing Generalizability Theory, particularly a corresponding software tool G-String.

Generalizability Analysis (GA) is a statistical method for analyzing the validity of psychometric assessment tools, such as structured performance examinations. GA is an extension of “Analysis of Variance” (ANOVA), and applying GA to any meaningful examination or test examining a non-trivial group of subjects, could involve hundreds, if not thousands of arithmetic operations and thus would be highly error-prone for manual processing. Almost universally, assessment practitioners today use specialized software tools for GA, such as G-String. These programs are highly efficient but completely non-transparent!

In this R Notebook I would like to demonstrate how to perform the ANOVA calculations required for GA transparently and efficiently using R. Here is a simple (p x i) design from “Generalizability Theory” by R. L. Brennan: Tables 2.2 and 2.3 on page 28.

Important !
If you want to actually download, and play around with the R script, you need to also download the files ‘DataMCQgh.png’ ‘ResultsBrennan.png’, scores.csv, ScoresMCQgh.csv and ‘Table_2_2.png’ from https://github.com/Papa-26/Brennan, and load them into the corresponding R working directory.


Tables 2.2 and 2.3 from “Generalizability Theory”

Maybe, I should quickly explain the nomenclature used in the R calculations, since ‘Rmd’, the code used for the calculations, uses a slightly different set of characters. But it is actually quite simple to understand the symbolic equivalences from these examples:

dfi -> \(df_{i}\)

Xpbar -> \(\overline{X}^2\)

SumXibar -> \(\sum_{i}\overline{X}^{2}_i\)

Erho2 -> \(E\rho^{2}\), etc.

Set Table 2.2

scores <- read.csv("scores.csv", header=FALSE)
# scores <- read.csv("ScoresMCQgh.csv", header=FALSE)

Calculate row, col, and gross mean

Xibar <- colMeans(scores)
Xpbar <- rowMeans(scores)
Xbar <- mean(Xpbar)

Calculate sample sizes (n) and degrees of freedom (df)

np <- nrow(scores)
ni <- ncol(scores)
dfp <- np -1
dfi <- ni -1
dfpi <- dfp * dfi

Calculate Sum Squares

SumXpbar2 <- sum(Xpbar^2)
SumXibar2 <- sum(Xibar^2)
SumXpibar2 <- sum(scores^2)

ANOVA

SS <- np * ni * Xbar ^ 2
SSp <- ni * SumXpbar2 - SS
SSi <- np * SumXibar2 - SS
SSpi <- SumXpibar2 - ni * SumXpbar2 - np * SumXibar2 + SS
MSp <- SSp / dfp
MSi <- SSi / dfi
MSpi <- SSpi / dfpi
sigma2p <- (MSp - MSpi)/ ni
sigma2i <- (MSi - MSpi)/ np
sigma2pi <- MSpi

Generalizability Coefficients

Erho2 <- sigma2p/(sigma2p + sigma2pi/ni)
Phi <- sigma2p/(sigma2p + (sigma2pi + sigma2i)/ni)

Results for Brennan’s Table 2.2 data

Side by side results from R and from “Generalizability Theory

In other words, the few R instructions give us the correct answers.


Results for Professor Hansen’s Tort MCQ

But there is more to it. We simply replace Brennan’s scores with those from the G-String website MCQ scores by commenting out ‘scores <- read.csv(“scores.csv”, header=FALSE)’, and removing the hash mark from ‘scores <- read.csv(“scoresMCQgh.csv”, header=FALSE)’. It takes less than a second for the new results:

R Analysis of website MCQ data
R Analysis of website MCQ data


When we compare this with the results from G-String:

   ANOVA


we see that sum scores and variance components are spot on! but let’s now look at the Generalizability Coefficients:

   Generalizability Coefficients


They too match the results from R. However, remember that this Multiple Choice Exam represents the simple (p x i) design, where the ANOVA was straight forward. When analyzing more complex designs, the calculations become much more complicated. G-String employs Brennan’s urGENOVA subroutine that uses elaborate iterative approaches, we can not easily replicate in simple R algorithms.


More elaborate R algorithms are available in an R-Package by Christopher T. Moore.

LS0tCnRpdGxlOiAiRy1TdHJpbmcgd2l0aCBSIgphdXRob3I6ICJSYWxwaCBCbG9jaCIKZGF0ZTogIjIwMjQtMDItMTciCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzInCiAgICBkZl9wcmludDogcGFnZWQKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMjIEludHJvZHVjdGlvbiB7I3NlYy1pbnRyb2R1Y3Rpb259CgpDZWxlYnJhdGluZyB5ZXQgYW5vdGhlciBiaXJ0aGRheSBzdXJyb3VuZGVkIGJ5IG15IGZhbWlseSwgSSB3YXMgcmVtaW5pc2NpbmcgYWJvdXQgYW5vdGhlciBiaXJ0aGRheSA3MCB5ZWFycyBhZ28gdGhhdCBkaXJlY3RlZCBtZSB0b3dhcmRzIGEgbGlmZSBpbiB0aGUgZXhhY3Qgc2NpZW5jZXMuIEl0IHdhcyB0aGUgaG9wZWQtZm9yIGJpcnRoZGF5IHByZXNlbnQ6IGEgMTIiIHNjaWVudGlmaWMgc2xpZGUgcnVsZS4gSXQgYWxsb3dlZCBtZSB0byBkbyBjb21wbGV4IGNhbGN1bGF0aW9ucyBlZmZpY2llbnRseSBhbmQgdHJhbnNwYXJlbnRseS4KCkF0IHByZXNlbnQgSSBhbSBzaW1pbGFybHkgYXdlZCBieSB0aGUgc2xpZGUgcnVsZSdzIDIxLiBjZW50dXJ5IHN1Y2Nlc3NvciAtICoqUioqLCBhIHRvb2wsIG5vIG1vZGVybiBzY2llbnRpc3Qgc2hvdWxkIGJlIHdpdGhvdXQuIEluIG15IGRvdGFnZSwgSSBzcGVuZCBtdWNoIHRpbWUgcG9wdWxhcml6aW5nIEdlbmVyYWxpemFiaWxpdHkgVGhlb3J5LCBwYXJ0aWN1bGFybHkgYSBjb3JyZXNwb25kaW5nIHNvZnR3YXJlIHRvb2wgW0ctU3RyaW5nXShodHRwczovL2dpdGh1Yi5jb20vRy1TdHJpbmctTGVnYWN5L0dTX01WKS4KCkdlbmVyYWxpemFiaWxpdHkgQW5hbHlzaXMgKEdBKSBpcyBhIHN0YXRpc3RpY2FsIG1ldGhvZCBmb3IgYW5hbHl6aW5nIHRoZSB2YWxpZGl0eSBvZiBwc3ljaG9tZXRyaWMgYXNzZXNzbWVudCB0b29scywgc3VjaCBhcyBzdHJ1Y3R1cmVkIHBlcmZvcm1hbmNlIGV4YW1pbmF0aW9ucy4gR0EgaXMgYW4gZXh0ZW5zaW9uIG9mICJBbmFseXNpcyBvZiBWYXJpYW5jZSIgKEFOT1ZBKSwgYW5kIGFwcGx5aW5nIEdBIHRvIGFueSBtZWFuaW5nZnVsIGV4YW1pbmF0aW9uIG9yIHRlc3QgZXhhbWluaW5nIGEgbm9uLXRyaXZpYWwgZ3JvdXAgb2Ygc3ViamVjdHMsIGNvdWxkIGludm9sdmUgaHVuZHJlZHMsIGlmIG5vdCB0aG91c2FuZHMgb2YgYXJpdGhtZXRpYyBvcGVyYXRpb25zIGFuZCB0aHVzIHdvdWxkIGJlIGhpZ2hseSBlcnJvci1wcm9uZSBmb3IgbWFudWFsIHByb2Nlc3NpbmcuIEFsbW9zdCB1bml2ZXJzYWxseSwgYXNzZXNzbWVudCBwcmFjdGl0aW9uZXJzIHRvZGF5IHVzZSBzcGVjaWFsaXplZCBzb2Z0d2FyZSB0b29scyBmb3IgR0EsIHN1Y2ggYXMgRy1TdHJpbmcuIFRoZXNlIHByb2dyYW1zIGFyZSBoaWdobHkgZWZmaWNpZW50IGJ1dCBjb21wbGV0ZWx5IG5vbi10cmFuc3BhcmVudCEKCkluIHRoaXMgUiBOb3RlYm9vayBJIHdvdWxkIGxpa2UgdG8gZGVtb25zdHJhdGUgaG93IHRvIHBlcmZvcm0gdGhlIEFOT1ZBIGNhbGN1bGF0aW9ucyByZXF1aXJlZCBmb3IgR0EgdHJhbnNwYXJlbnRseSBhbmQgZWZmaWNpZW50bHkgdXNpbmcgKipSKiouIEhlcmUgaXMgYSBzaW1wbGUgKHAgeCBpKSBkZXNpZ24gZnJvbSAiR2VuZXJhbGl6YWJpbGl0eSBUaGVvcnkiIGJ5IFIuIEwuIEJyZW5uYW46IFRhYmxlcyAyLjIgYW5kIDIuMyBvbiBwYWdlIDI4LgoKKipJbXBvcnRhbnQgISoqXApJZiB5b3Ugd2FudCB0byBhY3R1YWxseSBkb3dubG9hZCwgYW5kIHBsYXkgYXJvdW5kIHdpdGggdGhlIFIgc2NyaXB0LCB5b3UgbmVlZCB0byBhbHNvIGRvd25sb2FkIHRoZSBmaWxlcyAnRGF0YU1DUWdoLnBuZycgJ1Jlc3VsdHNCcmVubmFuLnBuZycsIHNjb3Jlcy5jc3YsIFNjb3Jlc01DUWdoLmNzdiBhbmQgJ1RhYmxlXzJfMi5wbmcnIGZyb20gPGh0dHBzOi8vZ2l0aHViLmNvbS9QYXBhLTI2L0JyZW5uYW4+LCBhbmQgbG9hZCB0aGVtIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgUiB3b3JraW5nIGRpcmVjdG9yeS4KClxwYWdlYnJlYWsKCjxici8+ICFbVGFibGVzIDIuMiBhbmQgMi4zIGZyb20gIkdlbmVyYWxpemFiaWxpdHkgVGhlb3J5Il0oVGFibGVfMl8yLnBuZykgPGJyLz48YnIvPiBNYXliZSwgSSBzaG91bGQgcXVpY2tseSBleHBsYWluIHRoZSBub21lbmNsYXR1cmUgdXNlZCBpbiB0aGUgKipSKiogY2FsY3VsYXRpb25zLCBzaW5jZSAnUm1kJywgdGhlIGNvZGUgdXNlZCBmb3IgdGhlIGNhbGN1bGF0aW9ucywgdXNlcyBhIHNsaWdodGx5IGRpZmZlcmVudCBzZXQgb2YgY2hhcmFjdGVycy4gQnV0IGl0IGlzIGFjdHVhbGx5IHF1aXRlIHNpbXBsZSB0byB1bmRlcnN0YW5kIHRoZSBzeW1ib2xpYyBlcXVpdmFsZW5jZXMgZnJvbSB0aGVzZSBleGFtcGxlczoKCj4gZGZpIC1cPiAkZGZfe2l9JAoKPiBYcGJhciAtXD4gJFxvdmVybGluZXtYfV4yJAoKPiBTdW1YaWJhciAtXD4gJFxzdW1fe2l9XG92ZXJsaW5le1h9XnsyfV9pJAoKPiBFcmhvMiAtXD4gJEVccmhvXnsyfSQsIGV0Yy4KCiMjIFNldCBUYWJsZSAyLjIgeyNzZWMtc2V0LXRhYmxlLTIuMn0KCmBgYHtyfQpzY29yZXMgPC0gcmVhZC5jc3YoInNjb3Jlcy5jc3YiLCBoZWFkZXI9RkFMU0UpCiMgc2NvcmVzIDwtIHJlYWQuY3N2KCJTY29yZXNNQ1FnaC5jc3YiLCBoZWFkZXI9RkFMU0UpCmBgYAoKIyMgQ2FsY3VsYXRlIHJvdywgY29sLCBhbmQgZ3Jvc3MgbWVhbgoKYGBge3J9ClhpYmFyIDwtIGNvbE1lYW5zKHNjb3JlcykKWHBiYXIgPC0gcm93TWVhbnMoc2NvcmVzKQpYYmFyIDwtIG1lYW4oWHBiYXIpCmBgYAoKIyMgQ2FsY3VsYXRlIHNhbXBsZSBzaXplcyAobikgYW5kIGRlZ3JlZXMgb2YgZnJlZWRvbSAoZGYpCgpgYGB7cn0KbnAgPC0gbnJvdyhzY29yZXMpCm5pIDwtIG5jb2woc2NvcmVzKQpkZnAgPC0gbnAgLTEKZGZpIDwtIG5pIC0xCmRmcGkgPC0gZGZwICogZGZpCmBgYAoKIyMgQ2FsY3VsYXRlIFN1bSBTcXVhcmVzCgpgYGB7cn0KU3VtWHBiYXIyIDwtIHN1bShYcGJhcl4yKQpTdW1YaWJhcjIgPC0gc3VtKFhpYmFyXjIpClN1bVhwaWJhcjIgPC0gc3VtKHNjb3Jlc14yKQpgYGAKCiMjIEFOT1ZBCgpgYGB7cn0KU1MgPC0gbnAgKiBuaSAqIFhiYXIgXiAyClNTcCA8LSBuaSAqIFN1bVhwYmFyMiAtIFNTClNTaSA8LSBucCAqIFN1bVhpYmFyMiAtIFNTClNTcGkgPC0gU3VtWHBpYmFyMiAtIG5pICogU3VtWHBiYXIyIC0gbnAgKiBTdW1YaWJhcjIgKyBTUwpNU3AgPC0gU1NwIC8gZGZwCk1TaSA8LSBTU2kgLyBkZmkKTVNwaSA8LSBTU3BpIC8gZGZwaQpzaWdtYTJwIDwtIChNU3AgLSBNU3BpKS8gbmkKc2lnbWEyaSA8LSAoTVNpIC0gTVNwaSkvIG5wCnNpZ21hMnBpIDwtIE1TcGkKYGBgCgojIyBHZW5lcmFsaXphYmlsaXR5IENvZWZmaWNpZW50cwoKYGBge3J9CkVyaG8yIDwtIHNpZ21hMnAvKHNpZ21hMnAgKyBzaWdtYTJwaS9uaSkKUGhpIDwtIHNpZ21hMnAvKHNpZ21hMnAgKyAoc2lnbWEycGkgKyBzaWdtYTJpKS9uaSkKYGBgCgpccGFnZWJyZWFrCgojIyBSZXN1bHRzIGZvciBCcmVubmFuJ3MgVGFibGUgMi4yIGRhdGEKCiFbU2lkZSBieSBzaWRlIHJlc3VsdHMgZnJvbSBSIGFuZCBmcm9tICJHZW5lcmFsaXphYmlsaXR5IFRoZW9yeV0oUmVzdWx0c0JyZW5uYW4ucG5nKSA8YnI+CgpJbiBvdGhlciB3b3JkcywgdGhlIGZldyBSIGluc3RydWN0aW9ucyBnaXZlIHVzIHRoZSBjb3JyZWN0IGFuc3dlcnMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClxuZXdwYWdlCgojIyBSZXN1bHRzIGZvciBQcm9mZXNzb3IgSGFuc2VuJ3MgVG9ydCBNQ1EKCkJ1dCB0aGVyZSBpcyBtb3JlIHRvIGl0LiBXZSBzaW1wbHkgcmVwbGFjZSBCcmVubmFuJ3Mgc2NvcmVzIHdpdGggdGhvc2UgZnJvbSB0aGUgRy1TdHJpbmcgd2Vic2l0ZSBNQ1Egc2NvcmVzIGJ5IGNvbW1lbnRpbmcgb3V0ICdzY29yZXMgXDwtIHJlYWQuY3N2KCJzY29yZXMuY3N2IiwgaGVhZGVyPUZBTFNFKScsIGFuZCByZW1vdmluZyB0aGUgaGFzaCBtYXJrIGZyb20gJ3Njb3JlcyBcPC0gcmVhZC5jc3YoInNjb3Jlc01DUWdoLmNzdiIsIGhlYWRlcj1GQUxTRSknLiBJdCB0YWtlcyBsZXNzIHRoYW4gYSBzZWNvbmQgZm9yIHRoZSBuZXcgcmVzdWx0czoKCiFbUiBBbmFseXNpcyBvZiB3ZWJzaXRlIE1DUSBkYXRhXShEYXRhTUNRZ2gucG5nKQoKPGJyPgoKV2hlbiB3ZSBjb21wYXJlIHRoaXMgd2l0aCB0aGUgcmVzdWx0cyBmcm9tIEctU3RyaW5nOgoKfCAgICAhW0FOT1ZBXShBTk9WQS5wbmcpCgo8YnI+IHdlIHNlZSB0aGF0IHN1bSBzY29yZXMgYW5kIHZhcmlhbmNlIGNvbXBvbmVudHMgYXJlIHNwb3Qgb24hIGJ1dCBsZXQncyBub3cgbG9vayBhdCB0aGUgR2VuZXJhbGl6YWJpbGl0eSBDb2VmZmljaWVudHM6Cgp8ICAgICFbR2VuZXJhbGl6YWJpbGl0eSBDb2VmZmljaWVudHNdKEdDLnBuZykKCjxicj4gVGhleSB0b28gbWF0Y2ggdGhlIHJlc3VsdHMgZnJvbSBSLiBIb3dldmVyLCByZW1lbWJlciB0aGF0IHRoaXMgTXVsdGlwbGUgQ2hvaWNlIEV4YW0gcmVwcmVzZW50cyB0aGUgc2ltcGxlIChwIHggaSkgZGVzaWduLCB3aGVyZSB0aGUgQU5PVkEgd2FzIHN0cmFpZ2h0IGZvcndhcmQuIFdoZW4gYW5hbHl6aW5nIG1vcmUgY29tcGxleCBkZXNpZ25zLCB0aGUgY2FsY3VsYXRpb25zIGJlY29tZSBtdWNoIG1vcmUgY29tcGxpY2F0ZWQuIEctU3RyaW5nIGVtcGxveXMgQnJlbm5hbidzIHVyR0VOT1ZBIHN1YnJvdXRpbmUgdGhhdCB1c2VzIGVsYWJvcmF0ZSBpdGVyYXRpdmUgYXBwcm9hY2hlcywgd2UgY2FuIG5vdCBlYXNpbHkgcmVwbGljYXRlIGluIHNpbXBsZSBSIGFsZ29yaXRobXMuCgo8YnI+TW9yZSBlbGFib3JhdGUgUiBhbGdvcml0aG1zIGFyZSBhdmFpbGFibGUgaW4gYW4gW1ItUGFja2FnZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2d0aGVvcnkvZ3RoZW9yeS5wZGYpIGJ5IENocmlzdG9waGVyIFQuIE1vb3JlLgo=