Începând cu [1] şi [2] folosim R şi instrumentăm "examenul de evaluare naţională" din 2015. Din [2] deducem că aproape 80% dintre elevi au obţinut medii peste 5 şi cam 13% dintre aceştia au medii în intervalul [9, 10] - ceea ce poate să pară mulţumitor; dar la fel de bine citind, faptul că o cincime de absolvenţi de învăţământ obligatoriu primesc medii sub 5 (deşi în cataloage au toţi peste 5), iar media generală a examenului este abia 6.78 - poate îndreptăţi o stare de alarmă generală (mai ţinând seama şi de nivelul rudimentar al subiectelor): învăţământul nostru "general şi obligatoriu" promovează şi produce mediocritate şi submediocritate.
Faţă de [1] şi [2] ar mai fi de investigat (poate aflăm ceva nou?) repartiţia rezultatelor după "Mediu" - un factor cu nivelele "RURAL" şi "URBAN", din structura de date evna constituită în [1] (şi salvată pe la începutul lui [2], în fişierul "evna.RData"). De exemplu, la judeţul Vaslui avem din [2] media 6.296, cu 27.22% medii sub 5 şi pe de altă parte - avem această structură de referinţă: trei municipii, două oraşe, 81 comune, 465 localităţi şi 533 unităţi şcolare; ar fi de văzut dacă şi în ce măsură s-ar explica nivelul mediilor prin rangul localităţilor unde se află şcolile din care provin elevii…
Recuperăm setul de date 'evna' şi îl reducem la variabilele care ne interesează acum - codul judeţului, mediul în care se încadrează şcoala din care provine candidatul şi media finală a acestuia:
load('evna.RData') evna <- subset(evna, select=c('Cod_siiir', 'Mediu', 'Media')) colnames(evna) <- c('jud', 'Mediu', 'media')
Inspectăm structura de date rezultată şi constatăm că 'media' este un "factor":
> str(evna)
'data.frame': 163418 obs. of 3 variables:
$ jud : Factor w/ 42 levels "01","02","03",..: 40 40 40 40 40 40 40 40 40 40 ...
$ Mediu: Factor w/ 2 levels "RURAL","URBAN": 2 2 2 2 2 2 2 2 2 2 ...
$ media: Factor w/ 705 levels "","1","10","1.02",..: 135 313 261 467 419 367 303 ...
>
Transformăm factorul 'media' în variabilă de tip numeric şi instituim (folosind funcţia cut()) variabila 'gap' - "factor" cu nivelele [1, 5), [5, 6), ..., [9, 10], prin care clasificăm mediile respective:
evna$media <- as.numeric(as.character(evna$media)) evna$gap <- cut(evna$media, breaks=c(1, 5:9, 10.01), right=FALSE)
Extragem aleatoriu un număr de rânduri de date, pentru a arăta structurarea actuală a datelor:
> evna[sample(nrow(evna), 3), ]
jud Mediu media gap
139749 29 RURAL 8.55 [8,9) # elev de la o şcoală din mediul rural, jud. Prahova, cu media între 8 şi 9
30137 04 URBAN 5.65 [5,6) # elev de la o şcoală din mediul urban, jud. Bacău, cu media în [5, 6)
35887 40 URBAN 8.57 [8,9)
>
Avem de obţinut frecvenţa mediilor din fiecare interval, pentru cele două categorii de mediu, din fiecare judeţ. În acest scop, vom folosi unele funcţii din pachetele plyr şi reshape2:
library(plyr); library(reshape2) evna.gap.freq <- ddply(evna, .(jud, Mediu, gap), summarise, freq=length(media))
Am angajat funcţia ddply() pentru a grupa după judeţ, mediu şi interval de medii, determinând pentru fiecare astfel de grup de linii de date numărul de elevi corespunzător, în noua variabilă 'freq':
> head(evna.gap.freq, 7)
jud Mediu gap freq
1 01 RURAL [1,5) 334 # 334 elevi din jud. Alba, din mediul rural, au medii [1, 5)
2 01 RURAL [5,6) 171
3 01 RURAL [6,7) 178
4 01 RURAL [7,8) 175
5 01 RURAL [8,9) 141
6 01 RURAL [9,10) 98 # de fapt (din definiţia 'cut()' mai sus) [9, 10.01) - încât este inclus şi 10
7 01 RURAL <NA> 46 # 46 elevi din jud. Alba, din mediul rural, au lipsit la o probă sau alta
>
Avem câte 14 totalizări pentru fiecare judeţ (7 la 'RURAL' şi 7 la 'URBAN'), exceptând 'M.Bucureşti' la care avem numai 7 - deci evna.gap.freq are exact 41*14+7 = 581 linii de date; ultimele 2*14 dintre acestea corespund (câte 14) judeţelor Călăraşi (de cod 51) şi Giurgiu (de cod 52).
Pentru a putea compara judeţele între ele vom avea nevoie de procente, în loc de "freq". Mai întâi, grupăm şi contorizăm după judeţ şi mediu (şi restructurăm liniile, prin funcţia dcast()):
jud.mediu <- ddply(evna, .(jud, Mediu), summarise, freq=length(media)) jud.mediu <- dcast(jud.mediu, jud ~ Mediu)
Structura de date jud.mediu obţinută astfel conţine câte o linie pentru fiecare judeţ, cu numărul de elevi participanţi la examen din mediul rural şi respectiv din mediul urban, iar liniile respective sunt în aceeaşi ordine ca şi codurile judeţelor:
> jud.mediu
jud RURAL URBAN
1 01 1143 1701
2 02 1449 1914
... ... ... ...
27 27 3196 1662
... ... ... ...
39 39 1849 1112
40 40 NA 12052
41 51 1516 857
42 52 1743 686
>
Pentru a referi aceste 42 de linii din cele 581 de linii ale setului evna.gap.freq, adăugăm acestuia din urmă coloana 'jud.n' constituită succesiv (prin angajarea funcţiei rep()) din 14 valori 1, 14 valori 2, ..., 14 valori 39, 7 valori 40, 14 valori 41 şi 14 valori 42:
evna.gap.freq$jud.n <- c(rep(1:39, each=14), rep(40, 7), rep(41:42, each=14))
De exemplu, linia 366 din evna.gap.freq arată că 501 elevi din mediul rural din judeţul Neamţ (codul 27) au medii în intervalul [5, 6); întrucât la intrarea 27 în jud.mediu avem în coloana 'RURAL' valoarea 3196 (reprezentând numărul total de participanţi din mediul rural din judeţul Neamţ), rezultă că mediile [5, 6) au în cazul de faţă frecvenţa relativă 501/3196=0.15676 (15.67%):
> evna.gap.freq[sample(nrow(evna.gap.freq), 3), ]
jud Mediu gap freq jud.n
366 27 RURAL [5,6) 501 27 # linia 27 'jud.mediu' are RURAL=3196, deci frecvenţa relativă = 501/3196
504 36 URBAN <NA> 7 36
377 27 URBAN [9,10) 523 27 # frecvenţa relativă pentru [9,10] pe 'URBAN' va fi 523/1662
>
Angajând funcţia split(), despărţim evna.gap.freq în două părţi, după valorile factorului 'Mediu' şi determinăm pentru fiecare frecvenţele relative (aşa cum am exemplificat mai sus, împărţind valorile din coloana "freq" la valorile din "jud.mediu" de pe linia indicată de câmpul "jud.n", coloana 2 pentru "RURAL" şi respectiv coloana 3 pentru "URBAN") - iar apoi reunim părţile, folosind funcţia unsplit():
evna.spl <- split(evna.gap.freq, evna.gap.freq$Mediu) evna.spl$RURAL$freq <- evna.spl$RURAL$freq / jud.mediu[evna.spl$RURAL$jud.n, 2] evna.spl$URBAN$freq <- evna.spl$URBAN$freq / jud.mediu[evna.spl$URBAN$jud.n, 3] evna.gap.proc <- unsplit(evna.spl, evna.gap.freq$Mediu)
Încheiem întregul demers eliminând coloana "de lucru" 'jud.n' şi schimbând codurile de judeţ cu denumirile obişnuite, preluate dintr-un set de date constituit anterior în [1]:
evna.gap.proc$jud.n <- NULL levels(evna.gap.proc$jud) <- jud.csp$judeţ
Redăm parţial repartiţia pe judeţe, mediu de provenienţă şi intervale de medii care ne-a rezultat prin cele de mai sus:
> evna.gap.proc
jud Mediu gap freq
1 Alba RURAL [1,5) 0.29221 # 29.22% medii sub 5 în mediul rural, judeţul Alba
2 Alba RURAL [5,6) 0.14961
... ... ...
6 Alba RURAL [9,10) 0.08574
7 Alba RURAL <NA> 0.04024 # 4.02% absenţi, mediul rural, jud. Alba
8 Alba URBAN [1,5) 0.11640 # 11.64% medii sub 5 în mediul urban, judeţul Alba
9 Alba URBAN [5,6) 0.11052
... ... ...
13 Alba URBAN [9,10) 0.24397
14 Alba URBAN <NA> 0.01117 # 1.11% absenţi, mediul urban, jud. Alba
... ... ...
547 M.Bucureşti URBAN [1,5) 0.10919
... ... ...
552 M.Bucureşti URBAN [9,10) 0.28684
553 M.Bucureşti URBAN <NA> 0.00514
... ... ...
568 Giurgiu RURAL [1,5) 0.37349
... ... ...
580 Giurgiu URBAN [9,10) 0.16618
581 Giurgiu URBAN <NA> 0.02041
>
Schimbăm numele (ne pare mai simplu şi mai sugestiv '.jMgf' decât '.gap.proc') şi salvăm în directorul de lucru curent, structura de date respectivă:
evna.jMgf <- evna.gap.proc save(evna.jMgf, file='evna.jMgf.RData')
Urmează să ne ocupăm mai departe (în partea a II-a) de obţinerea şi formularea vizuală a unor statistici, pentru setul de date obţinut mai sus.
vezi Cărţile mele (de programare)