[1] Un set de date URÂT: rezultatele bacalaureatului (I: curăţarea datelor),
(II: statistici şi interpretări)
Proba de "evaluare a competenţelor lingvistice într-o limbă de circulaţie internaţională studiată pe parcursul învăţământului liceal" (sau "proba C") este reflectată în coloanele 14:18:
names(bac5)[14:18] "ITA" "ITC" # Înţelegerea Textului Audiat, respectiv Citit "PMS" "PMO" # Producerea de Mesaje Scrise, respectiv Orale "IO" # Interacţiune orală
Cele 5 coloane (de clasă factor) asociază fiecare, următoarele calificative:
levels(bac5$ITA) "-" # fără calificativ final (0..10 puncte) "A1" "A2" # Slab (11..30 puncte), respectiv Începător (31..60 puncte) "B1" "B2" # Mediu (61..80 puncte), respectiv Experimentat (81..100 puncte)
Listând câmpurile respective şi câmpul "STATUS
" din diverse înregistrări, putem observa la un moment dat că apare totuşi, o dilemă:
bac5[sample(1:nrow(bac5), 5), c(14:18, 24)] ITA ITC PMS PMO IO STATUS ITA ITC PMS PMO IO STATUS 42087 A1 A1 - B1 B1 Promovat 46410 - - - - - Promovat 140263 A2 B1 - A2 A2 Nepromovat 18362 - - - - - Absent 92828 A1 A1 - B1 A1 Absent
Candidatul care are '-' (o dată sau de mai multe ori) şi apare ca "Promovat
", cu siguranţă că a participat la "proba C" (neparticiparea ar fi atras "respins", în final) , iar "-" înseamnă punctaj 0..10; dar "Absent
" în cazul a 5 de '-' poate însemna fie că a avut punctaje 0..10 şi a lipsit la o altă probă, fie că a lipsit chiar la "proba C".
În tabelul iniţial (vezi [1]), exista o coloană "STATUS_C
" pe care se înregistra situaţia de "Absent" la "proba C" şi pe care noi am considerat anterior că o putem omite (împreună cu alte coloane de bifare a prezenţei). Dilema evidenţiată mai sus (chit că nu este una importantă) se poate rezolva numai recuperând cumva, coloana "STATUS_C
":
bac5_bis <- read.csv("bac15.csv") # recuperăm datele iniţiale levels(bac5_bis$STATUS_C) [1] "Absent" "Calificativ" "Certificat" "Eliminat"
Copiem "STATUS_C" în structura de date "bac5"; inspectând datele respective, constatăm că sunt foarte puţini eliminaţi şi decidem să unificăm nivelele "Absent
" şi "Eliminat
" - rămânând în final la două nivele ("resp
" şi "ok
"):
bac5$STATUS_C <- bac5_bis$STATUS_C subset(bac5, STATUS_C=="Absent") -> abs5; nrow(abs5) # 4282 "Absent" subset(bac5, STATUS_C=="Eliminat") -> elm5; nrow(elm5) # 15 "Eliminat" levels(bac5$STATUS_C)[c(1, 4)] <- "resp" # "resp" unifică "Absent" şi "Eliminat" levels(bac5$STATUS_C)[c(2, 3)] <- "ok"
Prin investigaţia desfăşurată mai sus, am creat unele structuri de date de care nu vom mai avea nevoie; să eliberăm memoria de obiectele respective:
ls() # listăm obiectele existente în memorie [1] "abs5" "bac5" "bac5_bis" "elm5" "resp" rm(list = ls()[-2]) # afară de al doilea ("bac5"), ştergem toate obiectele
Vrând să caracterizăm cumva, competenţa lingvistică reflectată de datele din "bac5" - putem ignora cele 4282+15 înregistrări pentru care avem "resp
" în coloana "STATUS_C
" (toate conţinând câte 5 valori '-' în coloanele 14:18):
lingv <- subset(bac5, STATUS_C != "resp", select=c(14:18))
În principiu, avem două posibilităţi de a obţine caracteristicile statistice elementare ale datelor respective: fie constituim tabele de frecvenţă pentru fiecare coloană în parte, fie constituim tabele de contingenţă, "încrucişând" câte doi din cei 5 factori. Putem obţine tabelele de frecvenţă folosind funcţia table()
, dar cu summary()
avem o redare mai concisă:
summary(lingv) ITA ITC PMS PMO IO - :12514 - :12250 - :49016 - :14206 - :14994 A1:19146 A1:19615 A1:26549 A1:29065 A1:28459 A2:62579 A2:74721 A2:28079 A2:31913 A2:31312 B1:40935 B1:45657 B1:26724 B1:31123 B1:30315 B2:29468 B2:12399 B2:34274 B2:58335 B2:59562
Însă astfel, am obţinut o matrice cu valori de tip caracter - greu de prelucrat pentru a obţine frecvenţele relative (de acestea am avea nevoie, dacă am vrea mai târziu să confruntăm rezultatele din 2015 cu cele din 2016, de exemplu). Funcţia table()
returnează direct frecvenţele respective - fără a converti la caracter şi a prelucra pentru a afişa concis şi frumos, cum face summary()
- încât este uşor să relativizăm în final rezultatele.
Imbricăm lapply()
pentru a aplica table()
fiecărei coloane din "lingv
" şi apoi pentru a transforma rezultatul prin funcţia indicată în argumentul "FUN
" - funcţie care foloseşte prop.table()
pentru a proporţiona valorile din tabelul respectiv faţă de totalul acestora, rotunjind apoi la a patra zecimală şi returnând procentul respectiv:
lapply(lapply(lingv,table), FUN=function(t) 100*round(prop.table(t), 4))
$ITA # Înţelegerea Textului Audiat - A1 A2 B1 B2 7.60 11.63 38.01 24.86 17.90 # predomină calitatea A2 şi B1 (31-60, 61-80 puncte) $ITC # Înţelegerea Textului Citit - A1 A2 B1 B2 7.44 11.91 45.38 27.73 7.53 # predomină calitatea A2 (31-60 puncte) $PMS # Producere de Mesaje Scrise - A1 A2 B1 B2 29.77 16.13 17.05 16.23 20.82 # predomină calitatea '-' (0-10 puncte) $PMO # Producere de Mesaje Orale - A1 A2 B1 B2 8.63 17.65 19.38 18.90 35.43 # predomină calitatea B2 (81-100 puncte) $IO # Interacţiune Orală - A1 A2 B1 B2 9.11 17.29 19.02 18.41 36.18 # predomină calitatea B2 (81-100 puncte)
Cel mai vizibil aspect (probabil, binecunoscut) este faptul că lumea se descurcă cel mai greu cu mesajele scrise: la PMS
avem aproape 30% de '-' (candidaţi cu punctaj 0-10), iar acest procent este mult mai mare decât toate celelalte de pe prima coloană (corespunzătoare calităţii '-').
Ar fi interesant să vedem (de exemplu) câţi au punctaj mic în primele două şi punctaj mare în ultimele două dintre cele cinci variabile (fiind de aşteptat că, dacă înţelegi greu ce zice altul atunci nu poţi interacţiona prea bine - deci, punctaj mic la primele ar trebui să însemne punctaj mic şi la ultimele); cerinţele de acest tip sunt modelate prin tabelul de contingenţă, în care avem frecvenţa fiecărei combinaţii de valori ale variabilelor respective:
table(lingv) -> lingv_contg lingv_contg[1, 1, 1, 1, 1] [1] 10110 # 10110 candidaţi (promovaţi sau nu) au '-' la toate cele 5 criterii lingvistice lingv_contg[5, 5, 5, 5, 5] [1] 4652 # 4652 candidaţi au 'B2' pe toate cele 5 nivele lingv_contg[1, 1, 2, 3, 1] [1] 0 # nici unul nu are '- - A1 A2 -' (respectiv pe 'ITA ITC PMS PMO IO')
Variabilele sunt indexate (de la 1) în mod implicit, în ordinea în care apar coloanele respective; valorile variabilelor sunt şi ele indexate în mod implicit (în ordinea punctajelor asociate); avem 5 variabile, fiecare cu câte 5 valori - astfel că avem 55 = 3125 combinaţii de valori, iar rezultatul "lingv_contg
" exemplificat mai sus asociază fiecăreia dintre acestea frecvenţa de apariţie în "lingv
" a combinaţiei respective.
Putem afişa mai compact (54=625 de linii, în loc de 3125) tabelul de contingenţă obţinut, folosind funcţia ftable()
- dar nu afişarea, ne interesează; cel mai convenabil este să restructurăm tabelul în modul nativ "data.frame" (facilitând accesarea, ordonarea, sumarizarea şi reprezentarea grafică):
as.data.frame(lingv_contg) -> lingv_ctg str(lingv_ctg) 'data.frame': 3125 obs. of 6 variables: $ ITA : Factor w/ 5 levels "-","A1","A2",..: 1 2 3 4 5 1 2 3 4 5 ... $ ITC : Factor w/ 5 levels "-","A1","A2",..: 1 1 1 1 1 2 2 2 2 2 ... $ PMS : Factor w/ 5 levels "-","A1","A2",..: 1 1 1 1 1 1 1 1 1 1 ... $ PMO : Factor w/ 5 levels "-","A1","A2",..: 1 1 1 1 1 1 1 1 1 1 ... $ IO : Factor w/ 5 levels "-","A1","A2",..: 1 1 1 1 1 1 1 1 1 1 ... $ Freq: int 10110 28 29 4 2 75 299 368 51 8 ...
Ordonăm descrescător după frecvenţe, transformăm în procente faţă de numărul de prezenţi şi listăm înregistrările la care avem măcar 2% candidaţi:
lingv_ctg[order(-lingv_ctg$Freq), ] -> lingv_ctg lingv_ctg$Freq <- 100*round(lingv_ctg$Freq / nrow(lingv), 4) lingv_ctg[lingv_ctg$Freq > 2, ] ITA ITC PMS PMO IO Freq 1 - - - - - 6.14 3120 B2 B1 B2 B2 B2 4.53 3119 B1 B1 B2 B2 B2 3.49 3125 B2 B2 B2 B2 B2 2.83 763 A2 A2 - A1 A1 2.75
Avem de recunoscut că rezultatele ca atare sunt oarecum dezamăgitoare pentru noi, care am făcut investigaţia redată mai sus: am muncit mult şi am obţinut ce?! - procente de ordin cel mult 6%… (compensând poate, prin evidenţierea unor căi tipice de lucru cu R). Însumând valorile din ultimele patru din cele cinci rânduri de rezultate redate mai sus, putem zice doar că 13-14% dintre candidaţi au obţinut rezultate bune (majoritare fiind 'B1' şi 'B2'), la cele cinci criterii de competenţă lingvistică.
vezi Cărţile mele (de programare)