momente şi schiţe de informatică şi matematică
To attain knowledge, write. To attain wisdom, rewrite.

Un set de date URÂT: rezultatele bacalaureatului (III: competenţe lingvistice)

bacalaureat | limbajul R
2016 aug

9.4 Nivelul competenţelor lingvistice într-o limbă străină

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)

docerpro | Prev | Next