momente şi schiţe de informatică şi matematică
anti point—and—click

Repartizarea pe zile a încadrării profesorilor (IV.bis)

R | orar şcolar
2021 jan

Folosul anonimizării

Pentru a aloca pe zile orele existente este firesc să parcurgem profesorii într-o ordine legată cumva de numărul de ore; funcţia set_zile() din [1] ordona profesorii unei clase după numărul de ore pe săptămână la acea clasă şi apoi le distribuia orele pe zile. De mai înainte încă, am „anonimizat” numele profesorilor (agreând pe cât putem opera parlamentară privitoare la „protecţia datelor personale”); acum vedem că putem şi profita de practica anonimizării, pentru a evita (în principiu) reordonarea ulterioară a datelor. Reluăm [2], cu anumite modificări (deocamdată păstrăm numele reale, ceea ce este firesc câtă vreme nu le publicăm):

    # orar-profesori .xlsx -->  data.frame (tibble) "orar.rds"
library(tidyverse)
library(readxl)
path <- "orarP.xlsx"  # 118 foi Excel, câte două foi de fiecare prof.:
                      #                numele (liceu, prof.) şi orarul său
lstDF <- path %>%
         excel_sheets() %>%
         set_names() %>%
         map(read_excel, path = path)  # listă de 118 obiecte DF
# adaugă nume-prof. din DF de rang impar, în DF-ul următor în listă
for(i in seq(1, 117, by=2)) {
    prof <- substring(names(lstDF[[i]])[2], 10)
    nr <- nrow(lstDF[[(i+1)]])
    lstDF[[(i+1)]]$prof <- rep(prof, nr)
}
# constituie un obiect 'tibble' din DF-urile de rang par ale listei
orarDF <- seq(2, 118, by=2) %>% 
          map_df(., function(i) lstDF[[i]]) %>%
          relocate(., prof, before=1) %>%
          rename(., zl = `...1`)
saveRDS(orarDF, file="orar.rds")  # 300x14; prof zl(ziua) 1:12(ora)
              # [1:2, 8] este (NA, "Rom\r\n11.D"), adică profesorul respectiv
              # este liber (NA) 'Lu' ora 6, iar 'Ma' ora a 6-a face "Rom" la 11.D

În orar.rds vom găsi dacă va fi nevoie, datele iniţiale (inclusiv, numele profesorilor), aşa cum au fost ele înscrise în fişierul Excel. Să normalizăm datele respective (v. [2]) şi acum, să şi anonimizăm numele profesorilor:

library(tidyverse)

Q <- readRDS("orar.rds") %>% 
     gather("ora", "obCls", 3:14) %>%
     separate(obCls, c("obj", "cls"), sep="\r\n") %>%
     filter(!is.na(cls)) %>%
     mutate(cls = sub(".", "", cls, fixed=TRUE)) 

srt <- sort(table(Q$prof), decreasing=TRUE)
Q$prof <- factor(Q$prof, levels=names(srt), ordered=TRUE)

numePr <- c(paste0("P0", (1:9)), paste0("P", (10:59)))
levels(Q$prof) <- numePr
# 'P01'..'P59' notează profesorii în ordinea descrescătoare a numărului de ore
Q %>% arrange(prof) %>%
      saveRDS(., "orarNorm.rds")  # 925x5  (<ord>prof zl ora obj cls)

orarNorm.rds reprezintă datele respective în „format lung” (sau „forma normală”); fiecare dintre variabile are acum propriul domeniu de valori (nu amestecăm obiecte şi clase). În plus, am eliminat valorile de „oră inexistentă” (ştiind când are efectiv ore, deducem şi când profesorul este liber) şi am şters caracterul excentric "." din numele claselor; iar acum, numele anonimizate ale profesorilor "P01".."P59" (în ordine alfabetică) desemnează profesorii în ordinea descrescătoare a numărului de ore pe săptămână (iar în final, prin arrange(), liniile de date au fost ordonate deja după acest criteriu).

Desigur, rămâne încă de văzut dacă, având astfel liniile – deja într-o ordine potrivită – va fi totuşi necesară vreo reordonare; cel mai mare număr de ore pe săptămână nu este totuna cu cel mai mare număr de ore pe clasa curentă (căreia i-am aplica să zicem, set_zile()): profesorul de Rel, sau cel de Ed.Viz de exemplu, poate să aibă multe ore pe săptămână, dar pe fiecare clasă are nu mai mult de una (excepţional, două).

vezi Cărţile mele (de programare)

docerpro | Prev | Next