Î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)