Ce script calcule les statistiques d’accord interjuge (kappa de Fleiss’) à chaque bloc de 5% du screening formel (≈ 341 références par bloc, 20 blocs au total).
Il lit le fichier CSV exporté depuis le fichier Excel sommaire, calcule le kappa nominal (INC / MAYBE / EXC) et le kappa binaire (retenu vs exclu), et affiche une décision claire.
Procédure à répéter pour chaque bloc :
.csv depuis l’onglet Kappa
du fichier sommaire ExcelSeuils de référence : - Kappa binaire ≥ 0.75 → excellent (Cicchetti, 1994) - Kappa nominal ≥ 0.60 → substantial (Landis & Koch, 1977) - 3 blocs consécutifs sous 0.60 (nominal) → recalibration ciblée MAYBE
Lit le fichier exporté depuis Excel. Les #N/A sont
convertis automatiquement en valeurs manquantes. Seules les références
avec exactement 2 votes sont conservées pour le calcul du kappa.
library(readr)
library(irr)
## Loading required package: lpSolve
df_raw <- read_csv(
"Title_Abstract (5%).csv",
locale = locale(encoding = "latin1"),
na = c("", "NA", "#N/A"),
col_types = cols(.default = "c")
)
# Colonnes 2 à 9 = Kappa N PLL, MAM, MF, EP, Kappa B PLL, MAM, MF, EP
kappa_cols <- as.data.frame(lapply(df_raw[, 2:9], as.numeric))
# Garder les références avec exactement 2 votes (sur les 4 colonnes nominales)
n_votes <- rowSums(!is.na(kappa_cols[, 1:4]))
kappa_valid <- kappa_cols[n_votes == 2, ]
cat("✅ Références importées :", nrow(df_raw), "\n")
## ✅ Références importées : 341
cat("✅ Références avec 2 votes :", nrow(kappa_valid), "\n")
## ✅ Références avec 2 votes : 338
cat("⚠️ Références exclues (< 2 votes) :", nrow(df_raw) - nrow(kappa_valid), "\n")
## ⚠️ Références exclues (< 2 votes) : 3
Le kappa nominal traite INC (1), EXC
(0) et MAYBE (2) comme trois catégories
distinctes.
Il mesure la cohérence dans l’usage de MAYBE entre les reviewers.
Seuil : κ ≥ 0.60 (Landis & Koch, 1977).
# Implémentation manuelle de Fleiss' kappa pour matrice creuse
fleiss_kappa_sparse <- function(mat, cats = c(0, 1, 2)) {
mat <- as.matrix(mat)
n_i <- rowSums(!is.na(mat))
mat <- mat[n_i >= 2, ]
n_i <- n_i[n_i >= 2]
n <- nrow(mat)
k <- length(cats)
freq <- matrix(0, nrow = n, ncol = k)
for (ci in seq_along(cats)) {
freq[, ci] <- rowSums(mat == cats[ci], na.rm = TRUE)
}
pj <- colSums(freq) / sum(n_i)
Pi <- rowSums(freq * (freq - 1)) / (n_i * (n_i - 1))
Pbar <- mean(Pi)
Pe <- sum(pj^2)
kappa <- (Pbar - Pe) / (1 - Pe)
list(kappa = round(kappa, 3), n = n, Pbar = round(Pbar, 3), Pe = round(Pe, 3))
}
mat_nominal_sparse <- as.matrix(kappa_valid[, 1:4])
res_nom <- fleiss_kappa_sparse(mat_nominal_sparse, cats = c(0, 1, 2))
k_nom <- res_nom$kappa
cat("Kappa nominal de Fleiss' :", k_nom, "\n")
## Kappa nominal de Fleiss' : 0.591
cat("N références analysées :", res_nom$n, "\n\n")
## N références analysées : 338
if (k_nom >= 0.80) {
cat("Interprétation : Almost perfect ✅\n")
} else if (k_nom >= 0.60) {
cat("Interprétation : Substantial — seuil atteint ✅\n")
} else {
cat("Interprétation : SOUS LE SEUIL (< 0.60) — surveiller ⚠️\n")
}
## Interprétation : SOUS LE SEUIL (< 0.60) — surveiller ⚠️
Le kappa binaire fusionne INC et MAYBE en une seule
catégorie « retenu » (1) contre EXC (0).
Il mesure l’accord sur la décision opérationnelle : est-ce que la
référence avance au full-text ?
Seuil : κ ≥ 0.75 (Cicchetti, 1994).
mat_binaire_sparse <- as.matrix(kappa_valid[, 5:8])
res_bin <- fleiss_kappa_sparse(mat_binaire_sparse, cats = c(0, 1))
k_bin <- res_bin$kappa
cat("Kappa binaire de Fleiss' :", k_bin, "\n")
## Kappa binaire de Fleiss' : 0.691
cat("N références analysées :", res_bin$n, "\n\n")
## N références analysées : 338
if (k_bin >= 0.75) {
cat("Interprétation : Excellent — seuil atteint ✅\n")
} else {
cat("Interprétation : SOUS LE SEUIL (< 0.75) — recalibration requise ❌\n")
}
## Interprétation : SOUS LE SEUIL (< 0.75) — recalibration requise ❌
##
## ❌ RECALIBRATION COMPLÈTE REQUISE
## Le kappa binaire (0.691) est sous le seuil de 0.75.
## Screening suspendu jusqu'à la recalibration.
##