Introducció a l’estadística amb R

Sessió 1 · Introducció a l’estadística i primers passos amb R i RStudio

Joel Ardiaca

Centre d’Estudis d’Opinió

19 d’octubre del 2026

Benvinguda

Benvinguda i presentacions

Joel Ardiaca

  • Estadístic i sociòleg
  • Analista de dades al Centre d’Estudis d’Opinió (CEO)
  • Faig servir R cada dia per treballar amb enquestes

I vosaltres?

  • Nom
  • Lloc de feina
  • Què us agradaria treure del curs?
  • Coneixements previs d’estadística
  • Heu programat mai? (R, Python, macros d’Excel, SPSS…)

Estructura del curs

Sessió Data Contingut
1 Dl. 19 d’octubre Introducció a l’estadística. R i RStudio: tipus de dades, importar i netejar dades
2 Dt. 27 d’octubre Estadística descriptiva i inferencial univariada: intervals de confiança i contrastos d’hipòtesis
3 Dl. 2 de novembre Estadística bivariada: taules de contingència, prova χ² i comparació de mitjanes
4 Dl. 9 de novembre Correlació i regressió lineal


  • 4 sessions de 4 hores (9:30 – 13:30), amb una pausa a mitja sessió
  • Tot el curs el farem amb R i RStudio, amb dades reals

Metodologia i avaluació

Metodologia

  • Explicació dels conceptes estadístics
  • Demostració en directe amb R
  • Pràctica: exercicis curts durant la sessió i un exercici final

Avaluació

  • Avaluació continuada
  • Lliurament de l’exercici pràctic de cada sessió, per correu electrònic
  • Assistència mínima del 75 % per obtenir el certificat

L’objectiu no és memoritzar codi: és entendre què fem amb les dades i interpretar bé els resultats.

Què farem avui?

Abans de la pausa

  1. Què és l’estadística i conceptes bàsics
  2. Què és R i què és RStudio
  3. Primers passos amb R: objectes, funcions i tipus de dades

Després de la pausa

  1. El tidyverse i les seves funcions principals
  2. Demo: importar, netejar i exportar dades
  3. Codi en l’era de la IA
  4. Exercici: preparar una base de dades

Què és l’estadística?

Per què és important l’estadística avui dia?

Tenim més dades que mai i més capacitat per recollir-les, organitzar-les i analitzar-les.

Però… tenir dades no equival a tenir informació ni coneixement.

L’estadística és l’eina que ens permet extreure informació valuosa de les dades, per entendre el món i prendre millors decisions.

Cicle d’anàlisi de les dades

Avui: importar i netejar · Sessions 2–4: visualitzar, modelitzar i comunicar

Els 3 grans blocs de l’estadística

1. Descriptiva

Resumir i presentar les dades de manera clara.

  • Mitjana, mediana, desviació…
  • Taules i gràfics

Ex.: edat mitjana de les persones usuàries d’un servei

Sessions 1–2

2. Inferencial

Treure conclusions sobre una població a partir d’una mostra.

  • Intervals de confiança
  • Contrastos d’hipòtesis

Ex.: amb 1.000 entrevistes, estimar el suport a una política

Sessió 2

3. Relacions i models

Relacionar variables, explicar o predir.

  • Taules de contingència, χ²
  • Correlació i regressió

Ex.: com influeixen els estudis i l’edat en la satisfacció amb un servei públic

Sessions 3–4

Població i mostra

  • Població: conjunt complet d’individus o elements sobre els quals volem obtenir informació
  • Mostra: subconjunt d’individus seleccionats de la població

Exemple
Població: la ciutadania de Catalunya
Mostra: 2.000 persones entrevistades pel CEO

L’estadística inferencial ens permet extreure conclusions sobre la població a partir de la mostra, amb una certa incertesa (marge d’error).

Unitats d’anàlisi

  • La unitat d’anàlisi és cada element del qual recollim dades: una fila de la base de dades
  • Cal distingir-la del nivell d’anàlisi: el nivell al qual volem treure conclusions

Exemple
Tenim dades de persones (unitat d’anàlisi: persona), però volem treure conclusions per províncies: canviem el nivell d’anàlisi agregant les dades.

Una fila = una unitat d’anàlisi. Ho tornarem a veure quan treballem amb R.

Tipus de variables

Categòriques (qualitatives)

  • Nominals: sense ordre
    sexe, municipi, titularitat del centre…
  • Ordinals: amb ordre
    grau d’acord, nivell d’estudis, molt / bastant / poc / gens…

Quantitatives (numèriques)

  • Discretes: valors comptables
    nombre de fills, nombre de trucades…
  • Contínues: qualsevol valor en un interval
    ingressos, temps de resposta, edat…

El tipus de variable determina quina anàlisi podem fer!

Quin tipus de variable és?

Variable Tipus
Comarca de residència Categòrica nominal
Satisfacció amb el servei (molt / bastant / poc / gens) Categòrica ordinal
Nombre de persones a la llar Quantitativa discreta
Temps d’espera (minuts) Quantitativa contínua
Simpatia cap a la UE (escala 0–10) Quantitativa discreta (o ordinal!)
Codi postal Categòrica nominal (encara que siguin números!)

Qualitat de les dades

Abans d’analitzar, cal revisar:

  • Valors perduts: cel·les buides, codis com 99 o 9999, “No ho sap / No contesta”
  • Codificacions incorrectes o inconsistents
  • Etiquetes errònies o confuses
  • Dades duplicades o inconsistents
  • Errors d’entrada o unitats barrejades

Una bona neteja evita biaixos i conclusions errònies. Avui aprendrem a fer-la amb R.

R i RStudio

Què és R?

  • Un llenguatge de programació pensat per a l’estadística i l’anàlisi de dades
  • Gratuït i de codi obert
  • Milers de paquets que n’amplien les funcions
  • Una comunitat molt gran: hi ha resposta per a gairebé tot
  • Molt utilitzat a universitats, centres de recerca, instituts d’estadística i administracions

Per què programar?

El codi és la recepta de l’anàlisi:

  • Queda escrit què hem fet
  • Es pot repetir amb dades noves
  • Es pot compartir i revisar

R comparat amb altres eines

Excel SPSS / Jamovi R
Cost Llicència Llicència / Gratuït Gratuït
Forma de treballar Clics i fórmules Menús Codi
Reproduïble Difícil Parcialment Sí
Volum de dades Limitat Mitjà Gran
Gràfics personalitzats Limitats Limitats Molt flexibles
Corba d’aprenentatge Suau Suau Més pronunciada

El preu inicial és aprendre a escriure codi. Avui comencem!

R i RStudio: el motor i el tauler

R

El motor: el programa que fa els càlculs.

Es pot fer servir sol, però és poc còmode.

RStudio

El tauler de comandament: l’entorn on escrivim el codi, veiem les dades, els gràfics i l’ajuda.

Necessita R instal·lat per funcionar.

Instal·lació (en aquest ordre): 1. R (cran.r-project.org) · 2. RStudio Desktop (posit.co)

Alternativa sense instal·lar res: Posit Cloud (posit.cloud), RStudio al navegador.

RStudio: els 4 panells

1 · Script (editor)

On escrivim i desem el codi (.R).

Executem amb Ctrl + Enter.

3 · Entorn (Environment)

Els objectes que tenim creats: dades, vectors, resultats…

2 · Consola

On R executa el codi i mostra els resultats.

Es pot escriure directament, però no es desa.

4 · Fitxers / Gràfics / Paquets / Ajuda

Navegador de fitxers, gràfics generats, paquets instal·lats i ajuda de les funcions.

Script o consola?

Consola

  • S’executa al moment
  • No es desa
  • Útil per a proves ràpides

Script (.R)

  • Es desa en un fitxer
  • Es pot tornar a executar
  • Sempre treballarem amb scripts
Drecera Què fa
Ctrl + Enter Executa la línia (o la selecció)
Alt + - Escriu <-
Ctrl + Shift + M Escriu el pipe |>
Tab Autocompleta noms de funcions i objectes
Ctrl + S Desa l’script

Projectes de RStudio

Un projecte és una carpeta amb tot el que necessitem per a una anàlisi:

sessio-1/
├── sessio_1.Rproj    ← obrim això
├── dades/
│   ├── enquesta_ceo.csv
│   └── competencies_basiques.csv
└── codi/
    ├── 01_primers_passos.R
    └── exercici_sessio_1.R
  • Obrint el fitxer .Rproj, R sap on som
  • Les rutes són relatives a la carpeta del projecte: "dades/enquesta_ceo.csv"
  • Ens estalviem rutes com "C:/Users/.../Documents/...", que només funcionen al nostre ordinador

Ara: descarregueu materials-sessio-1.zip de la web del curs, descomprimiu-lo, obriu sessio_1.Rproj i després codi/01_primers_passos.R.

Primers passos amb R

R com a calculadora

2 + 3
[1] 5
10 / 4
[1] 2.5
(5 + 3) * 2
[1] 16

Els resultats surten a la consola. El [1] indica que és el primer valor del resultat.

Objectes: guardar coses amb <-

edat <- 42
edat + 1
[1] 43
nom <- "Anna"
nom
[1] "Anna"

<- vol dir: guarda el que hi ha a la dreta amb el nom de l’esquerra. L’objecte apareix al panell Entorn.

Els noms dels objectes: sense espais ni accents, millor en minúscules i amb _ (p. ex. edat_mitjana).

Vectors: diversos valors junts

Amb c() (de combinar) creem un vector:

edats <- c(34, 51, 28, 45, 39)
edats
[1] 34 51 28 45 39

Les operacions s’apliquen a tots els valors:

edats * 12
[1] 408 612 336 540 468
edats > 40
[1] FALSE  TRUE FALSE  TRUE FALSE

Funcions

Una funció fa una feina a partir d’uns arguments:

nom_funcio(argument1 = valor1, argument2 = valor2)
mean(edats)
[1] 39.4
max(edats)
[1] 51
round(3.14159, digits = 2)
[1] 3.14

Per saber com funciona una funció: ?mean o F1 amb el cursor a sobre del nom.

Tipus de dades a R

Tipus a R Exemple Tipus de variable estadística
numeric (<dbl>) 34, 7.5 Quantitativa (discreta o contínua)
character (<chr>) "Girona" Text: identificadors, o categòrica sense preparar
factor (<fct>) Poc, Molt Categòrica (nominal o ordinal)
logical (<lgl>) TRUE, FALSE Sí / No
NA NA Valor perdut (de qualsevol tipus)

Part de la neteja de dades és aconseguir que cada variable tingui el tipus correcte.

Factors: les variables categòriques

Si no diem res, R ordena les categories alfabèticament:

satisfaccio <- c("Poc", "Molt", "Bastant", "Poc")
factor(satisfaccio)
[1] Poc     Molt    Bastant Poc    
Levels: Bastant Molt Poc

Per a una variable ordinal, indiquem l’ordre amb levels:

factor(satisfaccio, levels = c("Gens", "Poc", "Bastant", "Molt"))
[1] Poc     Molt    Bastant Poc    
Levels: Gens Poc Bastant Molt

NA: valors perduts

ingressos <- c(1500, NA, 2100)
mean(ingressos)
[1] NA

R no pot calcular la mitjana si no sap un dels valors. Li hem de dir que els ignori:

mean(ingressos, na.rm = TRUE)
[1] 1800

A les dades reals, els valors perduts sovint no són NA: són 99, 9999, "No contesta"… Els haurem de convertir a NA.

Paquets

Un paquet afegeix funcions noves a R. És com una aplicació del mòbil:

S’instal·la una vegada

install.packages("tidyverse")

Es carrega cada vegada

library(tidyverse)


install.packages() va entre cometes: "tidyverse". library() no en necessita.

Taules de dades

Les dades amb què treballarem són taules (data frames o tibbles):

persones <- tibble(
  nom     = c("Anna", "Pau", "Marta", "Jordi", "Laia"),
  edat    = c(34, 51, 28, 45, 39),
  sexe    = c("D", "H", "D", "H", "D"),
  comarca = c("Gironès", "Segrià", "Barcelonès", "Tarragonès", "Barcelonès"),
  sou     = c(2100, 2800, NA, 2500, 1900)
)
persones
# A tibble: 5 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Anna     34 D     Gironès     2100
2 Pau      51 H     Segrià      2800
3 Marta    28 D     Barcelonès    NA
4 Jordi    45 H     Tarragonès  2500
5 Laia     39 D     Barcelonès  1900

Cada fila és una unitat d’anàlisi (una persona) i cada columna és una variable.

Formats de fitxers de dades

Format Què és Com s’importa a R
.csv Text separat per comes o per punts i comes read_csv() / read_csv2()
.xlsx Excel readxl::read_excel()
.sav SPSS haven::read_sav()
.rds Format propi de R (manté els tipus) readRDS()


CSV “europeu”: separador ; i decimals amb coma (3,5) → read_csv2()
CSV “anglès”: separador , i decimals amb punt (3.5) → read_csv()

Pausa ☕

Tornem en 30 minuts

El tidyverse

Què és el tidyverse?

  • Una col·lecció de paquets per treballar amb dades
  • Tots segueixen la mateixa lògica i la mateixa manera d’escriure
  • Funcions amb noms de verbs que s’entenen: selecciona, filtra, reanomena…
  • Amb library(tidyverse) els carreguem tots alhora
Paquet Per a què
readr Importar i exportar dades
dplyr Manipular dades
ggplot2 Gràfics
tidyr Reorganitzar taules
forcats Factors

Avui ens centrem en readr (importar i exportar) i dplyr (manipular).

Dades ordenades (tidy data)

  1. Cada variable és una columna
  2. Cada observació (unitat d’anàlisi) és una fila
  3. Cada valor és una cel·la

Imatge: Wickham, Çetinkaya-Rundel i Grolemund, R for Data Science (2a ed.)

El pipe |>: “i després”

El pipe passa el resultat de l’esquerra a la funció de la dreta. Es llegeix “i després”:

Sense pipe: es llegeix de dins cap a fora

select(filter(persones, edat > 35), nom, edat)

Amb pipe: es llegeix de dalt a baix

persones |>
  filter(edat > 35) |>
  select(nom, edat)

“Agafa persones, i després filtra les de més de 35 anys, i després selecciona el nom i l’edat.”

La taula d’exemple

persones
# A tibble: 5 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Anna     34 D     Gironès     2100
2 Pau      51 H     Segrià      2800
3 Marta    28 D     Barcelonès    NA
4 Jordi    45 H     Tarragonès  2500
5 Laia     39 D     Barcelonès  1900

Farem servir aquesta taula de 5 persones per veure cada funció.

select(): triar columnes

persones |>
  select(nom, edat)
# A tibble: 5 × 2
  nom    edat
  <chr> <dbl>
1 Anna     34
2 Pau      51
3 Marta    28
4 Jordi    45
5 Laia     39
persones |>
  select(-comarca)
# A tibble: 5 × 4
  nom    edat sexe    sou
  <chr> <dbl> <chr> <dbl>
1 Anna     34 D      2100
2 Pau      51 H      2800
3 Marta    28 D        NA
4 Jordi    45 H      2500
5 Laia     39 D      1900

Amb el - davant: totes menys aquesta.

filter(): triar files

persones |>
  filter(edat > 35)
# A tibble: 3 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Pau      51 H     Segrià      2800
2 Jordi    45 H     Tarragonès  2500
3 Laia     39 D     Barcelonès  1900
persones |>
  filter(comarca == "Barcelonès",
         edat < 35)
# A tibble: 1 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Marta    28 D     Barcelonès    NA
== igual != diferent > >= més gran < <= més petit !is.na(x) no és perdut

Atenció: per comparar es fa servir == (dos iguals). Un sol = s’usa per als arguments.

rename(): canviar noms de columnes

persones |>
  rename(salari = sou)
# A tibble: 5 × 5
  nom    edat sexe  comarca    salari
  <chr> <dbl> <chr> <chr>       <dbl>
1 Anna     34 D     Gironès      2100
2 Pau      51 H     Segrià       2800
3 Marta    28 D     Barcelonès     NA
4 Jordi    45 H     Tarragonès   2500
5 Laia     39 D     Barcelonès   1900


rename(nom_nou = nom_antic): el nom nou a l’esquerra.

mutate(): crear o modificar columnes

persones |>
  mutate(sou_anual = sou * 14)
# A tibble: 5 × 6
  nom    edat sexe  comarca      sou sou_anual
  <chr> <dbl> <chr> <chr>      <dbl>     <dbl>
1 Anna     34 D     Gironès     2100     29400
2 Pau      51 H     Segrià      2800     39200
3 Marta    28 D     Barcelonès    NA        NA
4 Jordi    45 H     Tarragonès  2500     35000
5 Laia     39 D     Barcelonès  1900     26600

Si fem servir un nom que ja existeix, la columna es modifica:

persones |>
  mutate(edat = edat + 1)
# A tibble: 5 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Anna     35 D     Gironès     2100
2 Pau      52 H     Segrià      2800
3 Marta    29 D     Barcelonès    NA
4 Jordi    46 H     Tarragonès  2500
5 Laia     40 D     Barcelonès  1900

mutate() + case_when(): recodificar

case_when(condició ~ valor_nou, ...)

persones |>
  mutate(sexe = case_when(
    sexe == "D" ~ "Dona",
    sexe == "H" ~ "Home"
  ))
# A tibble: 5 × 5
  nom    edat sexe  comarca      sou
  <chr> <dbl> <chr> <chr>      <dbl>
1 Anna     34 Dona  Gironès     2100
2 Pau      51 Home  Segrià      2800
3 Marta    28 Dona  Barcelonès    NA
4 Jordi    45 Home  Tarragonès  2500
5 Laia     39 Dona  Barcelonès  1900
persones |>
  mutate(grup_edat = case_when(
    edat < 35  ~ "Menys de 35",
    edat >= 35 ~ "35 o més"
  ))
# A tibble: 5 × 6
  nom    edat sexe  comarca      sou grup_edat  
  <chr> <dbl> <chr> <chr>      <dbl> <chr>      
1 Anna     34 D     Gironès     2100 Menys de 35
2 Pau      51 H     Segrià      2800 35 o més   
3 Marta    28 D     Barcelonès    NA Menys de 35
4 Jordi    45 H     Tarragonès  2500 35 o més   
5 Laia     39 D     Barcelonès  1900 35 o més   

Tot junt

1persones_net <- persones |>
2  select(nom, edat, sexe, sou) |>
3  rename(salari = sou) |>
4  mutate(sexe = case_when(sexe == "D" ~ "Dona",
                          sexe == "H" ~ "Home")) |>
5  filter(!is.na(salari))

persones_net
1
Agafa persones i guarda el resultat a persones_net…
2
…i després tria 4 columnes…
3
…i després canvia el nom de sou per salari…
4
…i després recodifica el sexe…
5
…i després elimina les persones sense salari.

Tot junt

# A tibble: 4 × 4
  nom    edat sexe  salari
  <chr> <dbl> <chr>  <dbl>
1 Anna     34 Dona    2100
2 Pau      51 Home    2800
3 Jordi    45 Home    2500
4 Laia     39 Dona    1900

Xuleta de funcions

Funció Què fa Exemple
read_csv2() Importa un CSV (;) dades <- read_csv2("dades/fitxer.csv")
glimpse() Mostra l’estructura glimpse(dades)
select() Tria columnes select(edat, sexe)
filter() Tria files filter(edat >= 18)
rename() Canvia noms rename(edat = EDAT)
mutate() Crea o modifica columnes mutate(edat2 = edat^2)
case_when() Recodifica (dins de mutate) case_when(x == 99 ~ NA, .default = x)
write_csv2() Exporta a CSV (;) write_csv2(dades, "dades/net.csv")
|> “i després” dades |> filter(...) |> select(...)

El teu torn (8’)

A partir de la taula persones (secció 9 de 01_primers_passos.R):

  1. Queda’t amb les persones de 30 anys o més
  2. Crea una columna sou_anual (sou × 14)
  3. Queda’t només amb les columnes nom i sou_anual
persones |>
  filter(   ) |>
  mutate(   ) |>
  select(   )

Solució

persones |>
  filter(edat >= 30) |>
  mutate(sou_anual = sou * 14) |>
  select(nom, sou_anual)
# A tibble: 4 × 2
  nom   sou_anual
  <chr>     <dbl>
1 Anna      29400
2 Pau       39200
3 Jordi     35000
4 Laia      26600

La Marta no surt perquè té 28 anys (i, de fet, era qui tenia el sou perdut, NA).

Demo: importar, netejar i exportar

Les dades: una enquesta del CEO

400 respostes i 11 variables d’una enquesta del Centre d’Estudis d’Opinió:

Variable Contingut
ID_ANONIM Identificador anònim
SEXE, PROVINCIA, ANY_NAIXEMENT, LLOC_NAIX Característiques sociodemogràfiques
SIMPATIA_UE, SIMPATIA_USA, SIMPATIA_RUSSIA Simpatia (0 = cap, 10 = molta)
BENESTAR_VACANCES Es pot permetre una setmana de vacances l’any?
SIT_ECO_PERSONAL_1_7 Situació econòmica personal (de molt dolenta a molt bona)
PREOCUPACIO_CONFLICTE Preocupació per un conflicte internacional (0–10)

Fitxer: dades/enquesta_ceo.csv

Pas 1 · Importar

read_csv("dades/enquesta_ceo.csv") |>
  glimpse()
Rows: 400
Columns: 1
$ `ID_ANONIM;SEXE;PROVINCIA;ANY_NAIXEMENT;LLOC_NAIX;SIMPATIA_UE;SIMPATIA_USA;SIMPATIA_RUSSIA;BENESTAR_VACANCES;SIT_ECO_PERSONAL_1_7;PREOCUPACIO_CONFLICTE` <chr> …

Una sola columna! El fitxer fa servir ; com a separador.

enquesta <- read_csv2("dades/enquesta_ceo.csv")

Ara sí: R ens informa que fa servir , com a decimal. Mirem què ha importat.

Pas 2 · Primer cop d’ull

glimpse(enquesta)
Rows: 400
Columns: 11
$ ID_ANONIM             <chr> "n4mskryleokr", "fb1zpr4ccrou", "si4cd…
$ SEXE                  <chr> "Femení", "Masculí", "Masculí", "Mascu…
$ PROVINCIA             <chr> "Barcelona", "Tarragona", "Barcelona",…
$ ANY_NAIXEMENT         <dbl> 1992, 1977, 2007, 1971, 1977, 1999, 19…
$ LLOC_NAIX             <chr> "Fora d'Espanya", "Catalunya", "Catalu…
$ SIMPATIA_UE           <dbl> 7, 7, 4, 7, 7, 7, 10, 9, 5, 3, 5, 10, …
$ SIMPATIA_USA          <dbl> 5, 6, 4, 5, 2, 6, 5, 5, 3, 2, 6, 10, 1…
$ SIMPATIA_RUSSIA       <dbl> 6, 3, 4, 4, 4, 0, 0, 2, 3, 2, 6, 0, 0,…
$ BENESTAR_VACANCES     <chr> "Sí", "Sí", "Sí", "No", "No", "Sí", "N…
$ SIT_ECO_PERSONAL_1_7  <chr> "Ni bona ni dolenta", "Més aviat bona"…
$ PREOCUPACIO_CONFLICTE <chr> "10 Molta preocupació", "6", "5", "8",…

Què hem de netejar?

Problema Solució
Noms en majúscules i llargs rename()
SEXE: “Femení” / “Masculí” mutate() + case_when()
SIMPATIA_*: el 9999 és un valor perdut case_when(x == 9999 ~ NA, ...)
“Valor perdut per omissió de resposta” case_when(x == "Valor..." ~ NA, ...)
PREOCUPACIO: és text (“10 Molta preocupació”) case_when() + as.numeric()
SIT_ECO: ordinal, però en text factor(levels = ...)
Volem l’edat, no l’any de naixement mutate(edat = 2025 - any_naixement)

Pas 3 · Seleccionar i reanomenar

enquesta_neta <- enquesta |>
  select(-ID_ANONIM) |>
  rename(
    sexe            = SEXE,
    provincia       = PROVINCIA,
    any_naixement   = ANY_NAIXEMENT,
    lloc_naixement  = LLOC_NAIX,
    simpatia_ue     = SIMPATIA_UE,
    simpatia_usa    = SIMPATIA_USA,
    simpatia_russia = SIMPATIA_RUSSIA,
    vacances        = BENESTAR_VACANCES,
    sit_economica   = SIT_ECO_PERSONAL_1_7,
    preocupacio     = PREOCUPACIO_CONFLICTE
  )
names(enquesta_neta)
 [1] "sexe"            "provincia"       "any_naixement"  
 [4] "lloc_naixement"  "simpatia_ue"     "simpatia_usa"   
 [7] "simpatia_russia" "vacances"        "sit_economica"  
[10] "preocupacio"    

Pas 4 · Recodificar i valors perduts

enquesta_neta <- enquesta_neta |>
  mutate(
    sexe = case_when(sexe == "Femení"  ~ "Dona",
                     sexe == "Masculí" ~ "Home"),
    simpatia_ue     = case_when(simpatia_ue == 9999     ~ NA, .default = simpatia_ue),
    simpatia_usa    = case_when(simpatia_usa == 9999    ~ NA, .default = simpatia_usa),
    simpatia_russia = case_when(simpatia_russia == 9999 ~ NA, .default = simpatia_russia),
    vacances = case_when(vacances == "Valor perdut per omissió de resposta" ~ NA,
                         .default = vacances)
  )

.default = x vol dir: tot el que no compleixi cap condició, deixa’l com estava.

Pas 5 · De text a número

preocupacio té els extrems de l’escala amb etiqueta: "0 Cap preocupació", "10 Molta preocupació".

enquesta_neta <- enquesta_neta |>
  mutate(
    preocupacio = case_when(
      preocupacio == "0 Cap preocupació"                    ~ "0",
      preocupacio == "10 Molta preocupació"                 ~ "10",
      preocupacio == "Valor perdut per omissió de resposta" ~ NA,
      .default = preocupacio
    ),
    preocupacio = as.numeric(preocupacio)
  )
enquesta_neta |> select(preocupacio) |> glimpse()
Rows: 400
Columns: 1
$ preocupacio <dbl> 10, 6, 5, 8, 6, 6, 10, 7, 5, 7, 0, 4, 8, 8, 4, 0…

Pas 6 · Crear variables noves

enquesta_neta <- enquesta_neta |>
  mutate(
    edat = 2025 - any_naixement,
    grup_edat = case_when(
      edat < 35  ~ "Menys de 35",
      edat < 50  ~ "35-49",
      edat < 65  ~ "50-64",
      edat >= 65 ~ "65 o més"
    )
  )

case_when() avalua les condicions per ordre: una persona de 40 anys no compleix edat < 35, però sí edat < 50, i es queda a “35-49”.

Pas 7 · Variables ordinals

enquesta_neta <- enquesta_neta |>
  mutate(
    sit_economica = case_when(
      sit_economica == "Valor perdut per omissió de resposta" ~ NA,
      .default = sit_economica
    ),
    sit_economica = factor(sit_economica,
                           levels = c("Molt dolenta", "Dolenta", "Més aviat dolenta",
                                      "Ni bona ni dolenta",
                                      "Més aviat bona", "Bona", "Molt bona"))
  )

Pas 8 · Comprovar sempre!

glimpse(enquesta_neta)
Rows: 400
Columns: 12
$ sexe            <chr> "Dona", "Home", "Home", "Home", "Dona", "Don…
$ provincia       <chr> "Barcelona", "Tarragona", "Barcelona", "Barc…
$ any_naixement   <dbl> 1992, 1977, 2007, 1971, 1977, 1999, 1955, 19…
$ lloc_naixement  <chr> "Fora d'Espanya", "Catalunya", "Catalunya", …
$ simpatia_ue     <dbl> 7, 7, 4, 7, 7, 7, 10, 9, 5, 3, 5, 10, 8, 10,…
$ simpatia_usa    <dbl> 5, 6, 4, 5, 2, 6, 5, 5, 3, 2, 6, 10, 1, 9, 4…
$ simpatia_russia <dbl> 6, 3, 4, 4, 4, 0, 0, 2, 3, 2, 6, 0, 0, 5, 2,…
$ vacances        <chr> "Sí", "Sí", "Sí", "No", "No", "Sí", "No", "S…
$ sit_economica   <fct> Ni bona ni dolenta, Més aviat bona, Més avia…
$ preocupacio     <dbl> 10, 6, 5, 8, 6, 6, 10, 7, 5, 7, 0, 4, 8, 8, …
$ edat            <dbl> 33, 48, 18, 54, 48, 26, 70, 69, 35, 41, 35, …
$ grup_edat       <chr> "Menys de 35", "35-49", "Menys de 35", "50-6…
enquesta_neta |> count(sexe)
# A tibble: 2 × 2
  sexe      n
  <chr> <int>
1 Dona    177
2 Home    223
enquesta_neta |> count(sit_economica)
# A tibble: 8 × 2
  sit_economica          n
  <fct>              <int>
1 Molt dolenta           9
2 Dolenta               14
3 Més aviat dolenta     61
4 Ni bona ni dolenta   120
5 Més aviat bona        95
6 Bona                  83
7 Molt bona             16
8 <NA>                   2

Pas 9 · Filtrar i exportar

Filtrar per mirar una part de les dades:

enquesta_neta |>
  filter(provincia == "Girona", grup_edat == "Menys de 35") |>
  select(sexe, edat, simpatia_ue, preocupacio)
# A tibble: 4 × 4
  sexe   edat simpatia_ue preocupacio
  <chr> <dbl>       <dbl>       <dbl>
1 Dona     26           7           6
2 Home     26          10           7
3 Home     25           9           7
4 Home     20           5           6

Exportar les dades netes:

write_csv2(enquesta_neta, "dades/enquesta_ceo_neta.csv")

Codi en l’era de la IA

No cal saber-ho tot de memòria

  • Ningú (tampoc qui programa cada dia) se sap totes les funcions
  • El que cal és saber llegir el codi i entendre què fa cada pas
  • Amb el que hem vist avui, ja podeu llegir la major part del codi de neteja de dades

Les eines d’IA (ChatGPT, Copilot, Claude, Gemini…) ens poden ajudar amb la sintaxi: com s’escriu una funció, què vol dir un error…

La IA escriu codi. Nosaltres decidim què volem fer i comprovem el resultat.

Mantenir el control

  1. Sé què vull fer, en paraules: “vull convertir els 9999 de simpatia_ue en valors perduts”
  2. Busco o demano el codi (ajuda, xuleta, cerca a internet o IA)
  3. Llegeixo el codi i entenc cada línia: si no l’entenc, no l’executo
  4. Executo i comprovo que el resultat és el que esperava: glimpse(), count()
# 1. Vull: convertir els 9999 de simpatia_ue en NA
enquesta_neta |>
  mutate(simpatia_ue = case_when(simpatia_ue == 9999 ~ NA,     # 3. Ho entenc?
                                 .default = simpatia_ue)) |>
  count(simpatia_ue)                                           # 4. Ho comprovo

Exercici

Exercici: competències bàsiques

Dades: dades/competencies_basiques.csv

Mostra de 500 alumnes de l’avaluació de competències bàsiques de 6è de primària (2023). Cada fila és un alumne.

Variable Contingut
CODI_ALUMNE Identificador anònim
PCAT, PMAT, PANG Puntuació (0–100) en català, matemàtiques i anglès
GENERE D = dona, H = home
ANY_NAIXEMENT Any de naixement
NATURALESA Titularitat del centre (Públic / Privat)
HABITAT Mida del municipi del centre
AREA_TERRITORIAL Àrea territorial del Departament d’Educació

Les mateixes dades que farem servir a la sessió 2 per a l’estadística descriptiva.

Què cal fer, pas a pas

  1. Carregar el tidyverse i importar les dades amb read_csv2()
  2. Mirar les dades amb glimpse(): quantes files i columnes? De quin tipus és cada variable?
  3. select(): quedar-se amb CODI_ALUMNE, GENERE, NATURALESA, HABITAT, PCAT, PMAT i PANG
  4. rename(): noms clars en minúscules (id, genere, titularitat, habitat, nota_cat…)
  5. mutate() + case_when(): recodificar genere (D → "Dona", H → "Home")
  1. mutate() + factor(): ordenar habitat de menys a més habitants
  2. mutate(): crear nota_mitjana (de les 3 notes) i nivell_mat amb case_when(): Baix (< 50), Mitjà (50–75), Alt (≥ 75)
  3. filter(): eliminar els alumnes sense nota de matemàtiques
  4. Escriure en un comentari una limitació d’aquestes dades
  5. Exportar amb write_csv2() a dades/competencies_basiques_net.csv

Què cal lliurar

  1. L’script exercici_sessio_1.R complet i comentat
  2. El fitxer competencies_basiques_net.csv

Per correu electrònic a joelardiacaarnau@gencat.cat

Consells

  • Obriu el projecte sessio_1.Rproj i després codi/exercici_sessio_1.R
  • Executeu línia a línia i comproveu el resultat de cada pas amb glimpse()
  • Si us encalleu: les slides (fan de xuleta), l’ajuda (?funcio), la IA… o pregunteu!

Tancament

Què hem après avui?

Estadística

  • Els 3 grans blocs de l’estadística
  • Població, mostra i unitat d’anàlisi
  • Tipus de variables
  • La importància de la qualitat de les dades

R i RStudio

  • RStudio: scripts i projectes
  • Objectes, vectors, funcions i paquets
  • Tipus de dades: numeric, character, factor, NA
  • Tidyverse: read_csv2, select, filter, rename, mutate, case_when, write_csv2


Propera sessió (dt. 27 d’octubre): estadística descriptiva i inferencial amb R