Estadistica descriptiva

Author

P. Loma-Osorio

Published

May 5, 2025



Estadística Descriptiva.


En aquest capitol importarem dades, els hi farem un cop d’ull, les netejarem i traballarem per ordenar-les i les descriurem individualment i per parelles. L’estadística descriptiva és sempre el primer pas de l’anàlisi de dades.




Posaré una llista de tasques habitual per l’análisis per tenir la de referència durant aquest capitol per tornar quan faci falta.

Passos habituals per fer una anàlisis de dades en R:

  1. IMPORTAR i INSPECCIONAR:
    1. Llegir les dades des d’un fitxer (read.csv, read_excel, readRDS, etc.).
    2. Verificar el format, tipus de variable, noms de columnes.
    3. Revisar valors perduts, duplicats o inconsistències.
    4. Funcions útils: str(), head(), summary(), glimpse()
  2. SELECCIONAR RECODIFICAR I ORDENAR:
    1. Seleccionar les columnes rellevants. select()
    2. Recodificar variables (mutate(), case_when(), factor())
    3. Ordenar observacions (arrange())
    4. Netejar valors atípics o mal codificats
  3. DESCRIURE LES DADES en el seu CONJUNT:
    1. Estadístics descriptius (mitjana, mediana, desviació típica, etc.)
    2. Taules de freqüència i proporcions
    3. Distribucions de variables contínues i categòriques
    4. Funcions: table(), summary(), mean(), sd(), count()
  4. RESUMIR, TRANSFORMAR i FILTRAR:
    1. Agrupar per categories. group_by()
    2. Resumir amb funcions estadístiques summarise()
    3. Filtrar subconjunts de interés filter()
    4. Crear noves variables o indicadors mutate()

Importem dades i fem un primer cop d’ull: Inspecció


Per començar importarem les dades dels supervivents del Titanic. Farem servir el sistema fàcil amb la pestanya de “import dataset”. Seleccionarem del nostre directori de treball l’arxiu “titanic.csv” i li assignarem un nom d’objecte que ens sigui entenedor. Per veure l’objecte fem servir View(). Podem confirmar quin tipus de dada és amb class(titanic).



titanic <- read.csv("titanic.csv")
#View (titanic)
class(titanic)
[1] "data.frame"


Fantàstic !!! hem descarregat unes dades en format dataframe i hem vist la pinta que té la taula, pero hem de saber mes. La funció glimpse() del paquet dplyr dóna molta informació de forma visualment atractiva.

Amb aquesta primera inspecció sabrem si s’ha carregat be l’informació, quants casos i variables tenim i quina estructura tenen. També i molt important revisem quants valors perduts tenim.

library(dplyr)
glimpse(titanic)
Rows: 891
Columns: 12
$ PassengerId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
$ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
$ Pclass      <int> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
$ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
$ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
$ Age         <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
$ SibSp       <int> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
$ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
$ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
$ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
$ Cabin       <chr> "", "C85", "", "C123", "", "", "E46", "", "", "", "G6", "C…
$ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…
#funcions d'inspeccio en R base
summary(titanic) 
  PassengerId       Survived          Pclass          Name          
 Min.   :  1.0   Min.   :0.0000   Min.   :1.000   Length:891        
 1st Qu.:223.5   1st Qu.:0.0000   1st Qu.:2.000   Class :character  
 Median :446.0   Median :0.0000   Median :3.000   Mode  :character  
 Mean   :446.0   Mean   :0.3838   Mean   :2.309                     
 3rd Qu.:668.5   3rd Qu.:1.0000   3rd Qu.:3.000                     
 Max.   :891.0   Max.   :1.0000   Max.   :3.000                     
                                                                    
     Sex                 Age            SibSp           Parch       
 Length:891         Min.   : 0.42   Min.   :0.000   Min.   :0.0000  
 Class :character   1st Qu.:20.12   1st Qu.:0.000   1st Qu.:0.0000  
 Mode  :character   Median :28.00   Median :0.000   Median :0.0000  
                    Mean   :29.70   Mean   :0.523   Mean   :0.3816  
                    3rd Qu.:38.00   3rd Qu.:1.000   3rd Qu.:0.0000  
                    Max.   :80.00   Max.   :8.000   Max.   :6.0000  
                    NA's   :177                                     
    Ticket               Fare           Cabin             Embarked        
 Length:891         Min.   :  0.00   Length:891         Length:891        
 Class :character   1st Qu.:  7.91   Class :character   Class :character  
 Mode  :character   Median : 14.45   Mode  :character   Mode  :character  
                    Mean   : 32.20                                        
                    3rd Qu.: 31.00                                        
                    Max.   :512.33                                        
                                                                          
names(titanic)
 [1] "PassengerId" "Survived"    "Pclass"      "Name"        "Sex"        
 [6] "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"       
[11] "Cabin"       "Embarked"   
head(titanic)
  PassengerId Survived Pclass
1           1        0      3
2           2        1      1
3           3        1      3
4           4        1      1
5           5        0      3
6           6        0      3
                                                 Name    Sex Age SibSp Parch
1                             Braund, Mr. Owen Harris   male  22     1     0
2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
3                              Heikkinen, Miss. Laina female  26     0     0
4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
5                            Allen, Mr. William Henry   male  35     0     0
6                                    Moran, Mr. James   male  NA     0     0
            Ticket    Fare Cabin Embarked
1        A/5 21171  7.2500              S
2         PC 17599 71.2833   C85        C
3 STON/O2. 3101282  7.9250              S
4           113803 53.1000  C123        S
5           373450  8.0500              S
6           330877  8.4583              Q
tail(titanic)
    PassengerId Survived Pclass                                     Name    Sex
886         886        0      3     Rice, Mrs. William (Margaret Norton) female
887         887        0      2                    Montvila, Rev. Juozas   male
888         888        1      1             Graham, Miss. Margaret Edith female
889         889        0      3 Johnston, Miss. Catherine Helen "Carrie" female
890         890        1      1                    Behr, Mr. Karl Howell   male
891         891        0      3                      Dooley, Mr. Patrick   male
    Age SibSp Parch     Ticket   Fare Cabin Embarked
886  39     0     5     382652 29.125              Q
887  27     0     0     211536 13.000              S
888  19     0     0     112053 30.000   B42        S
889  NA     1     2 W./C. 6607 23.450              S
890  26     0     0     111369 30.000  C148        C
891  32     0     0     370376  7.750              Q
colSums(is.na(titanic))
PassengerId    Survived      Pclass        Name         Sex         Age 
          0           0           0           0           0         177 
      SibSp       Parch      Ticket        Fare       Cabin    Embarked 
          0           0           0           0           0           0 
#analisis molon de missings
library(naniar)
Warning: el paquet 'naniar' es va construir amb la versió d'R 4.4.3
miss_var_summary(titanic)
# A tibble: 12 × 3
   variable    n_miss pct_miss
   <chr>        <int>    <num>
 1 Age            177     19.9
 2 PassengerId      0      0  
 3 Survived         0      0  
 4 Pclass           0      0  
 5 Name             0      0  
 6 Sex              0      0  
 7 SibSp            0      0  
 8 Parch            0      0  
 9 Ticket           0      0  
10 Fare             0      0  
11 Cabin            0      0  
12 Embarked         0      0  
vis_miss(titanic)

Tipus de variables.

Abans de continuar amb la descripció de les variables hem de tractar un punt molt important que és quins tipus de variables hem d’analitzar perquè en funció d’això aplicarem diferents mètodes. Aquí tenim un resum que s’ha d’entendre bé per continuar.




En resum les variables quantitatives són aquelles que es poden mesurar i representar conceptualment per un valor numéric i les qualitatives son aquelles que defineixen una característica que es pot representar per una etiqueta. Tenint en compte les peculiaritats:

  • Variables qualitatives
    • dicotomiques
    • nominals
    • ordinals
  • Variables quantitatives
    • contínues
    • discretes
    • ratio



Fem de nou un cop d’ull a les dades del Titànic i esbrinem quins tipus de variables hi ha segons la classificació previa.

glimpse(titanic)
Rows: 891
Columns: 12
$ PassengerId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
$ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
$ Pclass      <int> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
$ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
$ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
$ Age         <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
$ SibSp       <int> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
$ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
$ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
$ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
$ Cabin       <chr> "", "C85", "", "C123", "", "", "E46", "", "", "", "G6", "C…
$ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…

ULL: No confondre tipus de dades (datatypes) que és un concepte informàtic, amb tipus de variables.

Les variables quantitatives de “titanic” son: Age, Fare. Les variables qualitatives de “titanic” son: Survived, Pclass, Sex, SibSp (siblings or spouse), parch (parents or children aboard) , Cabin, Embarked (port d’embarcament: “C”: Cherbourg “Q”: Queenstown”S”: Southampton).



Ara et proposo un mini-exercici: carrega la matriu de dades de’Starwars i revisa quines variables conté i de quin tipus són. Analitza els missings. Construeix un vector amb les alçades dels personatges i un altra amb el sexe.

starwars<-starwars
glimpse(starwars)
Rows: 87
Columns: 14
$ name       <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia Or…
$ height     <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180, 2…
$ mass       <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, 77.…
$ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown", N…
$ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light", "…
$ eye_color  <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blue",…
$ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57.0, …
$ sex        <chr> "male", "none", "none", "male", "female", "male", "female",…
$ gender     <chr> "masculine", "masculine", "masculine", "masculine", "femini…
$ homeworld  <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan", "T…
$ species    <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "Huma…
$ films      <list> <"A New Hope", "The Empire Strikes Back", "Return of the J…
$ vehicles   <list> <"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, "Imp…
$ starships  <list> <"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced x1",…
miss_var_summary(starwars)
# A tibble: 14 × 3
   variable   n_miss pct_miss
   <chr>       <int>    <num>
 1 birth_year     44    50.6 
 2 mass           28    32.2 
 3 homeworld      10    11.5 
 4 height          6     6.90
 5 hair_color      5     5.75
 6 sex             4     4.60
 7 gender          4     4.60
 8 species         4     4.60
 9 name            0     0   
10 skin_color      0     0   
11 eye_color       0     0   
12 films           0     0   
13 vehicles        0     0   
14 starships       0     0   
sexe_galaxies<-(starwars$sex)
alt_galaxies<-(starwars$height)
summary(alt_galaxies)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   66.0   167.0   180.0   174.6   191.0   264.0       6 
summary(starwars$sex)
   Length     Class      Mode 
       87 character character 

Seleccionar, renombrar i ordenar

Quan hem importat unes dades i hem inspeccionat una mica l’estructura, particularment si son grans bases de dades, seleccionem les variables d’interès, els posem noms comodes per treballar, en alguns casos recodificarem la informació i ordenarem les columnes i casos per facilitar la comprensió global de l’informació.

Com varem avançar, la forma mes senzilla i entenedora de fer-lo, que constitueix un estàndar entre els usuaris de R es la libreria dplyr(), del paquet “dplyr”, inclosa dins del univers “tydiverse”. Permet utilizar una sintaxi mes natural a mes del ús de “pipes” o canonades %>% per fer multiples passos alhora.

Iniciarem amb les funcions mes sencilles: select(), rename(), arrange(). Les aplicarem a les dades del titanic.

Selecionar variables: select()

df %>% select(nom, edat) selecciona només aquestes columnes

df %>% select(-edat) # exclou la columna “edat”

df %>% select(starts_with(“var”)) # selecciona columnes que comencin per “var”

Renomenar columnes: rename()

df %>% rename(edat_anys = edat) # canvia el nom de “edat” a “edat_anys”

#seleccionem certes variables del dataframe
titanic %>% select(PassengerId, Age, Sex, Fare, Survived, Pclass) ->sel_titanic
sel_titanic <- sel_titanic %>% rename("clase" = "Pclass")
head(sel_titanic)
  PassengerId Age    Sex    Fare Survived clase
1           1  22   male  7.2500        0     3
2           2  38 female 71.2833        1     1
3           3  26 female  7.9250        1     3
4           4  35 female 53.1000        1     1
5           5  35   male  8.0500        0     3
6           6  NA   male  8.4583        0     3
sel_titanic %>% rename_with(tolower) ->sel_titanic2
head(sel_titanic2)
  passengerid age    sex    fare survived clase
1           1  22   male  7.2500        0     3
2           2  38 female 71.2833        1     1
3           3  26 female  7.9250        1     3
4           4  35 female 53.1000        1     1
5           5  35   male  8.0500        0     3
6           6  NA   male  8.4583        0     3


Ara anirem a ordenar les dades per una variable, per exemple el preu del passatge i posteriorment per dos, preu del passatge i edat.

Ordenar observacions: arrange()

df %>% arrange(edat) # ordena ascendent

df %>% arrange(desc(edat)) # ordena descendent

df %>% arrange(nom, desc(edat)) # ordena per nom i després edat descendent

sel_titanic2 %>% arrange(desc(fare)) -> sel_titanic_ord
head(sel_titanic_ord)
  passengerid age    sex     fare survived clase
1         259  35 female 512.3292        1     1
2         680  36   male 512.3292        1     1
3         738  35   male 512.3292        1     1
4          28  19   male 263.0000        0     1
5          89  23 female 263.0000        1     1
6         342  24 female 263.0000        1     1
sel_titanic2 %>% arrange(age, desc(fare)) -> sel_titanic_ord2
head(sel_titanic_ord2)
  passengerid  age    sex    fare survived clase
1         804 0.42   male  8.5167        1     3
2         756 0.67   male 14.5000        1     2
3         470 0.75 female 19.2583        1     3
4         645 0.75 female 19.2583        1     3
5          79 0.83   male 29.0000        1     2
6         832 0.83   male 18.7500        1     2


Descriptius de variables quantitatives.

Representació gràfica de les variables quantitatives

Tornem a identificar les variables quantitatives al dataframe titanic. Intentarem descriure-les. La funció summary te uns descriptius de la variable titanic$Age. Per saber si representaran bé la variable el primer pas és coneixer-ne l’aspecte. El més pràctic és representar-la gràficament. Per fer una representació gràfica ràpida de una variable tenim dues opcions: el diagrama de caixa (boxplot) i l’histograma. A continuació resumim l’anatomia d’un boxplot.

Per obtenir-ne un de bàsic en R és molt sencill:

boxplot(titanic$Age, horizontal = T, col = "red")

D’una altra banda l’histograma ens permet representar les dades quantitatives agrupades per freqüencies. El número de grups es pot seleccionar pero hi ha uns estándars que són els que per defecte posa R (formula de Sturges). És molt sencill fer un histograma bàsic en R.

hist(titanic$Age)


Mesures per descriure variables quantitatives.

1. Tendència central“on s’acumulen els valors?”

  • Mitjana: la mitjana aritmètica (la suma dividida pel nombre de valors). Exemple: mitjana d’edat = 52,3 anys.

    Mediana: el valor del mig (ordenats). Millor que la mitjana si hi ha valors extrems (outliers). Exemple: mediana = 48 anys.

    Moda: el valor que es repeteix més. Poc usada en quantitatives, però pot ser útil si hi ha pics.

2. Dispersió“com escampats estan els valors?”

  1. Rang: diferència entre el valor màxim i el mínim. Exemple: de 18 a 91 anys → rang = 73.

  2. Desviació estàndard (SD): quant es separen els valors de la mitjana. Valors més grans → més variabilitat.

  3. Variança: és el quadrat de la SD. Més tècnica, no es sol interpretar directament.

  4. Rang interquartílic (IQR): diferència entre el 3r i 1r quartil (Q3 - Q1).Mostra la dispersió del 50% central dels valors.

3. Posició o percentils

  • Quartils / percentils: divideixen els valors ordenats en parts iguals.

    • Q1 = 25% dels valors estan per sota

    • Q2 = 50% → la mediana

    • Q3 = 75% dels valors estan per sota

    • També pots mirar el percentil 5, 10, 90, etc. si vols saber els extrems.

4. Valors extrems i simetria:

  • Minim i màxim: El més petit i el mes gran.

  • Skewness (asimetria): indica si la distribució té cua cap a un costat.

  • Kurtosi: indica si hi ha més o menys valors als extrems del que seria normal.

Les mesures de tendència central tendeixen a convergir si la distribució es normal pero en cas contrari són altament informatives per separat. Les funcions més habituals per realitzar estadistica descriptiva univariada per dades quantitatives son aquests:

min(titanic$Age, na.rm=T)
[1] 0.42
range(titanic$Age, na.rm=T)
[1]  0.42 80.00
mean(titanic$Age)
[1] NA
mean(titanic$Age, na.rm = T)
[1] 29.69912
median(titanic$Age, na.rm = T)
[1] 28
quantile(titanic$Age, probs = c(5,10,15,20,25,30,50)/100, na.rm=T)
    5%    10%    15%    20%    25%    30%    50% 
 4.000 14.000 17.000 19.000 20.125 22.000 28.000 
var(titanic$Age,na.rm = T)
[1] 211.0191
sd (titanic$Age, na.rm= T)
[1] 14.5265
#una analis numerica complerta automàtica estaria al paquet psych::describe(titanic)

ULL: Si les dades contenen NAs, moltes funcions a R exigeixen que explicitament es treguin, com ara mean(). Es pot buscar ajuda de la funció help(mean), però provar na.rm = T sol funcionar (remove NA = true)


Freqüències

Una altra forma de descriure les dades quantitatives, particularment quan n’hi ha poques, és una taula de freqüències. Si són poques i es repeteixen podem fer una taula. Si són moltes podem crear intervals, però per evitar aquesta feina tenim un truc. Podem fer un histograma sense dibuixar-lo. Dóna els grups per la fórmula de Sturges (surt per defecte, però es poden definir els punts de tall), les freqüències relatives i les acumulades.

dades_numeriques<- sample(1:10, 20, replace = T)
table(dades_numeriques)
dades_numeriques
1 2 3 5 6 7 8 9 
3 2 3 1 4 4 1 2 
hist(titanic$Age, plot = F)
$breaks
[1]  0 10 20 30 40 50 60 70 80

$counts
[1]  64 115 230 155  86  42  17   5

$density
[1] 0.0089635854 0.0161064426 0.0322128852 0.0217086835 0.0120448179
[6] 0.0058823529 0.0023809524 0.0007002801

$mids
[1]  5 15 25 35 45 55 65 75

$xname
[1] "titanic$Age"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"


Outliers (Valors anomals)

Els outliers són valors atípics dins d’un conjunt de dades que es desvien significativament de la resta. Poden aparèixer per errors de mesura, introducció de dades incorrecta o perquè representen fenòmens reals poc freqüents. És important identificar-los, ja que poden distorsionar anàlisis estadístiques, afectant mitjanes, desviacions estàndard i resultats de models. Per detectar-los, s’utilitzen tècniques com els boxplots, l’IQR (rango interquartílic) o els z-scores. Un cop detectats, es poden eliminar, substituir per valors més representatius (com la mitjana o la mediana) o deixar-los, segons l’objectiu de l’anàlisi. Normalment es consideren outliers aquells valors separats mes de 1´5 vegades el valor minim o el maxim del rang interquartilic.

Per identificar-los, tant l’histograma com el boxplot son utilis, a mes l’objecte que R crea en fer un boxplot te una variable bp$out que els enmagatzema. Veiem un exemple:

xkp bp_age<-boxplot(titanic$Age, plot = F) bp_age$out}

També podem ordenar les dades de major a menor i veure els 10 primers valors doncs a vegades els metodes gràfics no ens permeten un bon análisi:

Métodes per tractar els outliers

En funció de l’analisis que necessitem fer, podem:

  • Substituirlos per NA.

  • Eliminar la fila sencera que conté el outlier

  • Imputar el valor de l’outlier (substituirlo per un altre valor, p.e la mitjana dels valors)

Posarem exemples amb titanic fare

#substituir per NA (quan hi han pocs)
titanic$Fare <- ifelse(titanic$Fare > 500, NA, titanic$Fare)   

#eliminar la fila (no he substituit l'objecte)  
titanic %>% select(Fare) %>%  filter(Fare <= 500) %>%   
  arrange(desc(Fare)) %>% head(10)   
       Fare
1  263.0000
2  263.0000
3  263.0000
4  263.0000
5  262.3750
6  262.3750
7  247.5208
8  247.5208
9  227.5250
10 227.5250
#imputar el valor amb la mitjana
mitjana <- mean(titanic$Fare, na.rm = TRUE)
titanic$Fare[is.na(titanic$Fare)] <- mitjana  
titanic %>% select(Fare) %>%  arrange(desc(Fare)) %>% head(10)
       Fare
1  263.0000
2  263.0000
3  263.0000
4  263.0000
5  262.3750
6  262.3750
7  247.5208
8  247.5208
9  227.5250
10 227.5250

Descriptius de variables qualitatives.


A R resumint tenim dos tipus de variables qualitatives: character i factor. Character es més genèrica i menys potent però permet traballar amb cadenes alfanumériques (pe CIP, ID de paciente etc) i factor es una variable categòrica estandar amb categories preestablertes. Si estan previament definides, R les recorda i les fa servir per etiquetar taules, gràfics etc. A més els factors poden guardar variables qualitatives ordinals.

Mesures per descriure variables qualitatives

1. Freqüències

  • Freqüència absoluta (n): nombre de casos en cada categoria. Exemple: 63 dones, 37 homes.

  • Freqüència relativa (%): proporció de cada categoria respecte al total. Exemple: 63% dones, 37% homes.

  • Freqüència acumulada: només s’aplica a variables ordinals (com ‘baixa’, ‘mitjana’, ‘alta’). Exemple: 30% baixa, 75% fins a mitjana, 100% fins a alta.

2. Moda

  • És la categoria més freqüent. Exemple: si el 70% dels pacients són “grup A”, la moda és “grup A”.


str(titanic)
'data.frame':   891 obs. of  12 variables:
 $ PassengerId: int  1 2 3 4 5 6 7 8 9 10 ...
 $ Survived   : int  0 1 1 1 0 0 0 0 1 1 ...
 $ Pclass     : int  3 1 3 1 3 3 1 3 3 2 ...
 $ Name       : chr  "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
 $ Sex        : chr  "male" "female" "female" "female" ...
 $ Age        : num  22 38 26 35 35 NA 54 2 27 14 ...
 $ SibSp      : int  1 1 0 1 0 0 0 3 0 1 ...
 $ Parch      : int  0 0 0 0 0 0 0 1 2 0 ...
 $ Ticket     : chr  "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
 $ Fare       : num  7.25 71.28 7.92 53.1 8.05 ...
 $ Cabin      : chr  "" "C85" "" "C123" ...
 $ Embarked   : chr  "S" "C" "S" "S" ...

Podem veure que no hi ha cap variable qualitativa definida com a factor i tot i que es pot treballar, és pitjor, per la qual cosa sempre que s’hagi de fer una anàlisi seriosa transformarem en factor i li donarem les categories.

La taula és el paradigma de la descripció de variables qualitatives, tant per obtenir les frequencies table() com per extreure’n les proporcions amb prop.table().

La representació gráfica es fa generalment amb gràfics de pastís o de barres. Posem exemples sencills.

tabla_sexe_titanic<- table (titanic$Sex)
prop.table(tabla_sexe_titanic)

  female     male 
0.352413 0.647587 
round(prop.table(tabla_sexe_titanic)*100,2)

female   male 
 35.24  64.76 
pie(tabla_sexe_titanic, col = c("pink", "blue"))

barplot(tabla_sexe_titanic, col=c("pink","blue"))

tabla_port_titanic<- table(titanic$Embarked)
tabla_port_titanic

      C   Q   S 
  2 168  77 644 
# hi han dos que no son NA pero no tenen assignat port
prop.table(tabla_port_titanic)

                      C           Q           S 
0.002244669 0.188552189 0.086419753 0.722783389 
round(prop.table(tabla_port_titanic)*100,2)

          C     Q     S 
 0.22 18.86  8.64 72.28 
pie(tabla_port_titanic)

barplot(tabla_port_titanic, col=c("orange","violet","green"))

# "C": Cherbourg "Q": Queenstown"S": Southampton

# forma de hacerlo directa con janitor()
library(janitor)
Warning: el paquet 'janitor' es va construir amb la versió d'R 4.4.3

S'està adjuntant el paquet: 'janitor'
Els següents objectes estan emmascarats des de 'package:stats':

    chisq.test, fisher.test
titanic %>% tabyl(Sex) %>% adorn_percentages("row") %>% adorn_totals()
    Sex         n     percent
 female 0.9988789 0.001121076
   male 0.9988789 0.001121076
  Total 1.9977578 0.002242152
titanic %>% tabyl(Embarked) %>% adorn_percentages("row") %>% adorn_totals()
 Embarked         n     percent
          0.9988789 0.001121076
        C 0.9988789 0.001121076
        Q 0.9988789 0.001121076
        S 0.9988789 0.001121076
    Total 3.9955157 0.004484305

Estadística descriptiva bivariada.

Aquesta part serveix per explicar com es comporten dos variables. És tan evident com sembla, sí, però la clave está en la intención del análisis. La estadística univariada describe; la bivariada relaciona.

Variables qualitatives: taules de contingència

Abans hem vist les taules unidimensionals, ara tractarem amb les taules 2x2 (o dos x n) o taules de contingència.

Anem a analitzar la supervivència des passatgers del titànic en funció de la classe del passatge (1, 2 ó 3era)

table(titanic$Survived, titanic$Pclass)
   
      1   2   3
  0  80  97 372
  1 136  87 119

La taula aporta informació pero sería mes sencilla d’analitzar si tenim les proporcions.

tabla1<-table(titanic$Survived, titanic$Pclass)
dimnames(tabla1)[[1]]<- c("morts","vius")
tabla1
       
          1   2   3
  morts  80  97 372
  vius  136  87 119
prop.table(tabla1)
       
                 1          2          3
  morts 0.08978676 0.10886644 0.41750842
  vius  0.15263749 0.09764310 0.13355780
# si no donem més informació sortiran les proporcions absolutes. Solen ser més informatives les relatives

prop.table(tabla1, margin = 1)
       
                1         2         3
  morts 0.1457195 0.1766849 0.6775956
  vius  0.3976608 0.2543860 0.3479532
prop.table(tabla1, margin = 2)
       
                1         2         3
  morts 0.3703704 0.5271739 0.7576375
  vius  0.6296296 0.4728261 0.2423625

Per visualitzar les dades una bona opció es el barplot (el més freqüent) o el mosaic. Ràpidament ens permetran emetre hipòtesis per esser testades amb el test adequat.

barplot(tabla1, beside = TRUE, legend.text = TRUE, col = c("brown", "lightgreen"))

mosaicplot(tabla1, col= c("pink", "orange", "brown"))

Hi han moltes alternatives per fer taules, per una molt utilitzada és `gmodels)

library(gmodels)
CrossTable(tabla1, prop.chisq = F)

 
   Cell Contents
|-------------------------|
|                       N |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|

 
Total Observations in Table:  891 

 
             |  
             |         1 |         2 |         3 | Row Total | 
-------------|-----------|-----------|-----------|-----------|
       morts |        80 |        97 |       372 |       549 | 
             |     0.146 |     0.177 |     0.678 |     0.616 | 
             |     0.370 |     0.527 |     0.758 |           | 
             |     0.090 |     0.109 |     0.418 |           | 
-------------|-----------|-----------|-----------|-----------|
        vius |       136 |        87 |       119 |       342 | 
             |     0.398 |     0.254 |     0.348 |     0.384 | 
             |     0.630 |     0.473 |     0.242 |           | 
             |     0.153 |     0.098 |     0.134 |           | 
-------------|-----------|-----------|-----------|-----------|
Column Total |       216 |       184 |       491 |       891 | 
             |     0.242 |     0.207 |     0.551 |           | 
-------------|-----------|-----------|-----------|-----------|

 

Un altra opció fent servir el ecosistema dplyr per estalviar crear la taula i despres la prop.table, es la llibreria janitor. Janitor tambe neteja i estandaritza automaticament els noms de les variables. Es molt utilitzada i te altres funcions utils (pe detectar duplicats o netejar columnes o files buides) que podeu consultar al seu manual.

library (janitor)
titanic %>% tabyl(Survived, Pclass) %>% adorn_percentages("col") %>% adorn_totals("col")
 Survived         1         2         3    Total
        0 0.3703704 0.5271739 0.7576375 1.655182
        1 0.6296296 0.4728261 0.2423625 1.344818
titanic_clean <-titanic %>% clean_names()
names(titanic_clean)
 [1] "passenger_id" "survived"     "pclass"       "name"         "sex"         
 [6] "age"          "sib_sp"       "parch"        "ticket"       "fare"        
[11] "cabin"        "embarked"    

Uns altres descriptius de una tabla de contingència son el OR i el RR. Creem una taula 2x2 per fer-ho més sencill.

tabla2<- table(titanic$Sex, titanic$Survived)
dimnames(tabla2)[[2]]<-c("mort", "viu")
tabla2
        
         mort viu
  female   81 233
  male    468 109
CrossTable(tabla2, chisq = F)

 
   Cell Contents
|-------------------------|
|                       N |
| Chi-square contribution |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|

 
Total Observations in Table:  891 

 
             |  
             |      mort |       viu | Row Total | 
-------------|-----------|-----------|-----------|
      female |        81 |       233 |       314 | 
             |    65.386 |   104.962 |           | 
             |     0.258 |     0.742 |     0.352 | 
             |     0.148 |     0.681 |           | 
             |     0.091 |     0.262 |           | 
-------------|-----------|-----------|-----------|
        male |       468 |       109 |       577 | 
             |    35.583 |    57.120 |           | 
             |     0.811 |     0.189 |     0.648 | 
             |     0.852 |     0.319 |           | 
             |     0.525 |     0.122 |           | 
-------------|-----------|-----------|-----------|
Column Total |       549 |       342 |       891 | 
             |     0.616 |     0.384 |           | 
-------------|-----------|-----------|-----------|

 

Odds Ratio (OR)

El odds ratio (OR) se utiliza en estadística para medir la asociación entre dos variables. La fórmula del odds ratio es:

[ OR = ]

Donde: - (a) es el número de sujetos expuestos que desarrollan el resultado. - (b) es el número de sujetos expuestos que no desarrollan el resultado. - (c) es el número de sujetos no expuestos que desarrollan el resultado. - (d) es el número de sujetos no expuestos que no desarrollan el resultado.

Risk Ratio (RR)

El risk ratio (RR), también conocido como razón de riesgos, es otra medida de asociación entre dos variables. La fórmula del risk ratio es:

[ RR = ]

Donde: - (a) es el número de sujetos expuestos que desarrollan el resultado. - (b) es el número de sujetos expuestos que no desarrollan el resultado. - (c) es el número de sujetos no expuestos que desarrollan el resultado. - (d) es el número de sujetos no expuestos que no desarrollan el resultado.

ULL: EL OR es fa servir freqüentment en estudis de casos i controls mentre que el RR es més comú en estudis de cohorts i assajos clinics. El OR tendeix a magnificar l’associació en esdeveniments raros .

Amb la llibreria epitoolspodem calcular OR, RR i els intervals de confiança

library(epitools)
oddsratio(tabla2)
$data
        
         mort viu Total
  female   81 233   314
  male    468 109   577
  Total   549 342   891

$measure
        odds ratio with 95% C.I.
          estimate     lower     upper
  female 1.0000000        NA        NA
  male   0.0813727 0.0583162 0.1124282

$p.value
        two-sided
         midp.exact fisher.exact   chi.square
  female         NA           NA           NA
  male            0 6.463922e-60 3.711748e-59

$correction
[1] FALSE

attr(,"method")
[1] "median-unbiased estimate & mid-p exact CI"
riskratio(tabla2)
$data
        
         mort viu Total
  female   81 233   314
  male    468 109   577
  Total   549 342   891

$measure
        risk ratio with 95% C.I.
          estimate     lower     upper
  female 1.0000000        NA        NA
  male   0.2545801 0.2123854 0.3051576

$p.value
        two-sided
         midp.exact fisher.exact   chi.square
  female         NA           NA           NA
  male            0 6.463922e-60 3.711748e-59

$correction
[1] FALSE

attr(,"method")
[1] "Unconditional MLE & normal approximation (Wald) CI"


Variables quantitatives: correlació

La forma de relacionar-se dues variables quantitatives es pot representar per la correlació. El coeficient de Pearson el indicador mes habitualment utilitzat. Si el coeficient es 0 indica que no hi ha correlació, si es 1 indica correlacció directa perfecta i -1 correlació inversa perfecta.

A mes de calcular aquest index es molt útil una representació gràfica.

titanic_sin_na<-na.omit(titanic)
cor(titanic_sin_na$Age, titanic_sin_na$Fare)
[1] 0.1002833
plot(titanic_sin_na$Age, titanic_sin_na$Fare)

#como es un ejemplo feo, vamos a elegir otro
cor(iris$Sepal.Length, iris$Petal.Length)
[1] 0.8717538
# Ajustar el modelo de regresión lineal
modelo_regresion <- lm(Petal.Length ~ Sepal.Length, data = iris)

# Crear el gráfico de dispersión
plot(iris$Sepal.Length, iris$Petal.Length, 
     xlab = "Sepal Length", ylab = "Petal Length", 
     main = "Diagrama de dispersión Sepal Length vs Petal Length")
abline(modelo_regresion, col = "red")

ULL: La correlació no és una mesura de la força de la relació o la seva importància. No captura les relacions no lineals ni pot detectar relacions causals.


Dos o més variables qualitatitatives i dos o mes variables quantitatives.

Agafem de nou les dades del titanic per fer descripcions una mica mes complexes.

boxplot(titanic$Fare~ titanic$Pclass, col=c("green", "yellow", "gray"))

# los outliers de primera clase me fan el grafic lleig
boxplot(titanic$Fare~ titanic$Pclass, col=c("green", "yellow", "gray"), ylim= c(0,200))

Per veure si les diferències que semblen es poden generalitzar, necessitarem un test d’hipótesis. Els contrastes d’hipòtesis els veurem en el següent capitol sobre estadística inferencial.


Seleccionar, renomenar, transformar, recalcular, recodificar variables.

Aquesta part és un mini tast d’operacions amb dplr per que vegeu el seu potencial. Sembla que s’ha d’apendre molt de codi però 99% de les vegades el ChatGPT l’encerta si se li pregunta correctament. Aquestes operacions també se simplifiquen molt en orígen. Un bon resum de les funcions de dplyr es pot trobar a aquesta pagina

Agrupar i resumir: group_by() i summarise()

Un dels recursos mes potents de dplyr es agrupar i resumir. Es poden aplicar tots els métodes de resum que hem vist abans (mitjana, mediana, percentatge etc). Un exemple Volem coneixer la mitjana de visites médiques en funció del ABS de referència partint d’una taula que te pacients, on consta l’abs i el número de visites.

pacients %>% group_by(abs) %>% summarise (mitjana visitas = mean(num_visites)

Tornem a la base de dades de Titanic: seleccionem només les variables que ens interessen: PassengerId, Age, Sex, Fare, Survived i Pclass. Canviem el nom de la variable Pclass. Després ordenarem les dades de major a menor preu del ticket. Semblaria que els que van pagar un tiquet car sobreviuen més. Agrupem la taula en funció de si van sobreviure, per si ens fes pinta que té a veure una cosa amb l’altra i també amb el sexe.

titanic %>% select(PassengerId, Age, Sex, Fare, Survived, Pclass) %>% arrange(-Fare)->sel_titanic

sel_titanic %>% rename("clase" = "Pclass") ->sel_titanic

head(sel_titanic)
  PassengerId Age    Sex    Fare Survived clase
1          28  19   male 263.000        0     1
2          89  23 female 263.000        1     1
3         342  24 female 263.000        1     1
4         439  64   male 263.000        0     1
5         312  18 female 262.375        1     1
6         743  21 female 262.375        1     1
titanic %>% group_by(Survived==1) %>% summarise(precio_medio_del_pasaje = mean(Fare))
# A tibble: 2 × 2
  `Survived == 1` precio_medio_del_pasaje
  <lgl>                             <dbl>
1 FALSE                              22.1
2 TRUE                               44.2
titanic %>% group_by(Sex) %>% summarise(media_de_precio_del_pasaje = mean(Fare))
# A tibble: 2 × 2
  Sex    media_de_precio_del_pasaje
  <chr>                       <dbl>
1 female                       42.9
2 male                         23.9


Filtrar: filter()

Ara filtrem per algunes variables: seleccionem només els viatgers que van pagar pel seu passatge. Amb dplyr es molt intuitiu, particularment si fem servir el “pipe”. Agafem les dades (dataframe, df) les enviem a la funció filter i entre parèntesi posem tantes condicions com ens interessi. El resultat el podem guardar en un nou objecte o veure’l per la consola.

df %>% filter (sexe == “dona”, edat<40)

seleccio_ulls_interessants <- df %>% filter (ulls != “marron”)

library(tidylog)
Warning: el paquet 'tidylog' es va construir amb la versió d'R 4.4.3

S'està adjuntant el paquet: 'tidylog'
Els següents objectes estan emmascarats des de 'package:dplyr':

    add_count, add_tally, anti_join, count, distinct, distinct_all,
    distinct_at, distinct_if, filter, filter_all, filter_at, filter_if,
    full_join, group_by, group_by_all, group_by_at, group_by_if,
    inner_join, left_join, mutate, mutate_all, mutate_at, mutate_if,
    relocate, rename, rename_all, rename_at, rename_if, rename_with,
    right_join, sample_frac, sample_n, select, select_all, select_at,
    select_if, semi_join, slice, slice_head, slice_max, slice_min,
    slice_sample, slice_tail, summarise, summarise_all, summarise_at,
    summarise_if, summarize, summarize_all, summarize_at, summarize_if,
    tally, top_frac, top_n, transmute, transmute_all, transmute_at,
    transmute_if, ungroup
L'objecte següent està emmascarat per 'package:stats':

    filter
titanic %>% filter(Fare!=0) -> sel2_titanic
filter: removed 15 rows (2%), 876 rows remaining
sel2_titanic %>% group_by(Survived==1) %>% summarise(precio_medio_del_pasaje = mean(Fare))
group_by: one grouping variable (Survived == 1)
summarise: now 2 rows and 2 columns, ungrouped
# A tibble: 2 × 2
  `Survived == 1` precio_medio_del_pasaje
  <lgl>                             <dbl>
1 FALSE                              22.7
2 TRUE                               44.3
sel2_titanic %>% group_by(Sex) %>% summarise(media_de_precio_del_pasaje = mean(Fare))
group_by: one grouping variable (Sex)
summarise: now 2 rows and 2 columns, ungrouped
# A tibble: 2 × 2
  Sex    media_de_precio_del_pasaje
  <chr>                       <dbl>
1 female                       42.9
2 male                         24.5

Quants valors “missing” o NA tenim a l’apartat edat? I a la taula en general? Podem treurel’s de la matriu de dades?

summary(titanic$Age)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   0.42   20.12   28.00   29.70   38.00   80.00     177 
sum(is.na(titanic$Age))
[1] 177
na_counts <- sel_titanic %>%  summarise_all(~sum(is.na(.)))
summarise_all: now one row and 6 columns, ungrouped
na_counts
  PassengerId Age Sex Fare Survived clase
1           0 177   0    0        0     0
sel_titanic %>% filter(!is.na(Age)) -> sense_na_titanic
filter: removed 177 rows (20%), 714 rows remaining
#View(sense_na_titanic)

summary(sense_na_titanic$Age)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.42   20.12   28.00   29.70   38.00   80.00 
sum(is.na(sense_na_titanic$Age))
[1] 0


<>

Transformar i recodificar: mutate()

Per ultim fem una transformació de dades. Mutate es mes complex per que te mes funcions a aplicar pero igualment de sintaxi senzilla.

df %>% mutate( edat_grup = case_when( edat < 18 ~ “menor”, edat >= 18 & edat < 65 ~ “adult”, edat >= 65 ~ “gent gran”))

df %>% mutate(es_major = if_else(edat >= 18, “sí”, “no”))

Als tiquets de menys de 10000 dollars els hi direm “barats” entre 10 i 100K els hi direm “apanyats” i els de més de 100K els hi direm “cars”. Crearem una variable nova dita “preu_categoria”.

sel_titanic %>% mutate(preu_categoria = cut(Fare, breaks=c(0,10,100, Inf), labels = c("barats","apanyats","cars" ))) ->sel3_titanic
mutate: new variable 'preu_categoria' (factor) with 4 unique values and 2% NA
table(sel3_titanic$preu_categoria)

  barats apanyats     cars 
     321      505       50 

ULL: A R ( i a altres llenguatges) el simbol “igual” té dos acepcions: la d’assignació ( en aquest cas = equival a <-) que és per nomenar objectes, i la d’operador logic que avalua si dos expresions són idèntiques. En aquest cas es posa un doble igual ==. De la mateixa forma l’operador lògic de desigualtat és !=

Grafics avançats: ggplot2

ggplot2 (https://ggplot2.tidyverse.org/) és un paquet de R per crear gràfics de manera elegant i coherent. Es basa en la “Gramàtica dels Gràfics”, un enfocament que defineix els components bàsics d’una visualització: dades, estètica (aes), geometries (geom), facetes, escales i temes. Permet construir gràfics pas a pas mitjançant capes, cosa que facilita la personalització i la reutilització del codi. És ideal per a visualització exploratòria i presentacions finals. Amb ggplot2, podem crear gràfics de barres, línies, punts, caixes, i molt més, controlant fàcilment colors, formes, eixos i llegendes.

La qualitat es altissima i no hi ha gràfic que no es pugui fer. La sintaxi és complicada però aqui es on més recomano el chatgpt per que encerta practicament sempre. Poso alguns exemples amb codi a sota.

library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point()

library(cowplot)
Warning: el paquet 'cowplot' es va construir amb la versió d'R 4.4.3
ggplot(iris, aes(Sepal.Length, fill = Species)) + 
  geom_density(alpha = 0.5) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  theme_minimal_hgrid(12)

library(ggsci)
Warning: el paquet 'ggsci' es va construir amb la versió d'R 4.4.3
p1 <- ggplot(
  subset(diamonds, carat >= 2.2),
  aes(x = table, y = price, colour = cut)
) +
  geom_point(alpha = 0.7) +
  geom_smooth(method = "loess", alpha = 0.05, linewidth = 1, span = 1) +
  theme_bw()

p1
`geom_smooth()` using formula = 'y ~ x'

ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl), size = hp)) +
  geom_point(alpha = 0.8) +
  geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dashed") +
  scale_color_brewer(palette = "Set1", name = "Cilindres") +
  labs(
    title = "Relació entre pes i consum",
    subtitle = "Base de dades mtcars",
    x = "Pes (milers de lliures)",
    y = "Milles per galó (mpg)",
    size = "Cavalls de potència (hp)"
  ) +
  theme_minimal(base_size = 14)
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
`geom_smooth()` using formula = 'y ~ x'
Warning: The following aesthetics were dropped during statistical transformation: size.
ℹ This can happen when ggplot fails to infer the correct grouping structure in
  the data.
ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
  variable into a factor?

ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
  geom_violin(trim = FALSE, alpha = 0.6) +
  geom_jitter(width = 0.1, size = 1.5, alpha = 0.8) +
  scale_fill_brewer(palette = "Pastel1") +
  labs(
    title = "Distribució de la longitud del sèpal",
    subtitle = "per espècie (iris dataset)",
    x = "Espècie",
    y = "Longitud del sèpal (cm)"
  ) +
  theme_minimal(base_size = 14) +
  theme(legend.position = "none")

També recomano fer una ullada a aquests exemples: https://exts.ggplot2.tidyverse.org/gallery/, https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/

Analisi exploratori de dades automàtic (EDA): skimr i DataExplorer

skimr és un paquet de R que proporciona una manera ràpida, clara i amigable de resumir dades. Ofereix resums estadístics personalitzats per a cada tipus de variable (numèrica, categòrica, dates, etc.) i millora la llegibilitat respecte a funcions com summary(). La funció principal, skim(), genera estadístiques com mitjana, desviació, valors nuls, percentils i distribucions en forma de mini-histogrames. És útil tant per a exploració inicial com per a documentació de conjunts de dades. Compatible amb pipes (%>%) i dades grans, skimr facilita una visió general ràpida i estructurada.

library(skimr)
Warning: el paquet 'skimr' es va construir amb la versió d'R 4.4.3

S'està adjuntant el paquet: 'skimr'
L'objecte següent està emmascarat per 'package:naniar':

    n_complete
skim(iris)
Data summary
Name iris
Number of rows 150
Number of columns 5
_______________________
Column type frequency:
factor 1
numeric 4
________________________
Group variables None

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
Species 0 1 FALSE 3 set: 50, ver: 50, vir: 50

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Sepal.Length 0 1 5.84 0.83 4.3 5.1 5.80 6.4 7.9 ▆▇▇▅▂
Sepal.Width 0 1 3.06 0.44 2.0 2.8 3.00 3.3 4.4 ▁▆▇▂▁
Petal.Length 0 1 3.76 1.77 1.0 1.6 4.35 5.1 6.9 ▇▁▆▇▂
Petal.Width 0 1 1.20 0.76 0.1 0.3 1.30 1.8 2.5 ▇▁▇▅▃
skim(titanic)
Data summary
Name titanic
Number of rows 891
Number of columns 12
_______________________
Column type frequency:
character 5
numeric 7
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Name 0 1 12 82 0 891 0
Sex 0 1 4 6 0 2 0
Ticket 0 1 3 18 0 681 0
Cabin 0 1 0 15 687 148 0
Embarked 0 1 0 1 2 4 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
PassengerId 0 1.0 446.00 257.35 1.00 223.50 446.00 668.5 891 ▇▇▇▇▇
Survived 0 1.0 0.38 0.49 0.00 0.00 0.00 1.0 1 ▇▁▁▁▅
Pclass 0 1.0 2.31 0.84 1.00 2.00 3.00 3.0 3 ▃▁▃▁▇
Age 177 0.8 29.70 14.53 0.42 20.12 28.00 38.0 80 ▂▇▅▂▁
SibSp 0 1.0 0.52 1.10 0.00 0.00 0.00 1.0 8 ▇▁▁▁▁
Parch 0 1.0 0.38 0.81 0.00 0.00 0.00 0.0 6 ▇▁▁▁▁
Fare 0 1.0 30.58 41.11 0.00 7.91 14.45 30.7 263 ▇▁▁▁▁
eda_titanic <-titanic %>% select(where(is.numeric)) %>%  skim()
select: dropped 5 variables (Name, Sex, Ticket, Cabin, Embarked)
View(eda_titanic)


titanic %>% group_by(Survived) %>%  skim()
group_by: one grouping variable (Survived)
Data summary
Name Piped data
Number of rows 891
Number of columns 12
_______________________
Column type frequency:
character 5
numeric 6
________________________
Group variables Survived

Variable type: character

skim_variable Survived n_missing complete_rate min max empty n_unique whitespace
Name 0 0 1 12 57 0 549 0
Name 1 0 1 12 82 0 342 0
Sex 0 0 1 4 6 0 2 0
Sex 1 0 1 4 6 0 2 0
Ticket 0 0 1 3 18 0 470 0
Ticket 1 0 1 4 17 0 260 0
Cabin 0 0 1 0 11 481 63 0
Cabin 1 0 1 0 15 206 102 0
Embarked 0 0 1 1 1 0 3 0
Embarked 1 0 1 0 1 2 4 0

Variable type: numeric

skim_variable Survived n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
PassengerId 0 0 1.00 447.02 260.64 1.00 211.00 455.0 675.00 891 ▇▆▇▇▇
PassengerId 1 0 1.00 444.37 252.36 2.00 250.75 439.5 651.50 890 ▆▇▇▇▆
Pclass 0 0 1.00 2.53 0.74 1.00 2.00 3.0 3.00 3 ▂▁▂▁▇
Pclass 1 0 1.00 1.95 0.86 1.00 1.00 2.0 3.00 3 ▇▁▅▁▇
Age 0 125 0.77 30.63 14.17 1.00 21.00 28.0 39.00 74 ▁▇▅▂▁
Age 1 52 0.85 28.34 14.95 0.42 19.00 28.0 36.00 80 ▃▇▅▂▁
SibSp 0 0 1.00 0.55 1.29 0.00 0.00 0.0 1.00 8 ▇▁▁▁▁
SibSp 1 0 1.00 0.47 0.71 0.00 0.00 0.0 1.00 4 ▇▅▁▁▁
Parch 0 0 1.00 0.33 0.82 0.00 0.00 0.0 0.00 6 ▇▁▁▁▁
Parch 1 0 1.00 0.46 0.77 0.00 0.00 0.0 1.00 5 ▇▁▁▁▁
Fare 0 0 1.00 22.12 31.39 0.00 7.85 10.5 26.00 263 ▇▁▁▁▁
Fare 1 0 1.00 44.17 50.26 0.00 12.47 26.0 56.82 263 ▇▂▁▁▁

DataExplorer és un paquet de R pensat per facilitar l’exploració de dades de manera ràpida, visual i automàtica. Amb només unes línies de codi, genera gràfics i informes complets sobre la forma, la distribució, els valors perduts i les relacions entre variables. Inclou funcions com plot_intro(), plot_missing(), plot_density() o create_report(), ideals per obtenir una visió general sense haver de programar gaire. És especialment útil per detectar problemes i preparar les dades abans de modelitzar. És una eina molt potent per principiants i també per usuaris avançats que volen agilitzar l’anàlisi exploratòria.

library(DataExplorer)
Warning: el paquet 'DataExplorer' es va construir amb la versió d'R 4.4.3
# Vista general de les dades
plot_intro(titanic)

# Valors perduts
plot_missing(titanic)

# Variables categòriques
plot_bar(titanic)
3 columns ignored with more than 50 categories.
Name: 891 categories
Ticket: 681 categories
Cabin: 148 categories

# Variables numèriques
plot_density(titanic)

# Informe complet en HTML
create_report(titanic)


processing file: report.rmd

  |                                           
  |                                     |   0%
  |                                           
  |.                                    |   2%                                 
  |                                           
  |..                                   |   5% [global_options]                
  |                                           
  |...                                  |   7%                                 
  |                                           
  |....                                 |  10% [introduce]                     
  |                                           
  |....                                 |  12%                                 
  |                                           
  |.....                                |  14% [plot_intro]                    

  |                                           
  |......                               |  17%                                 
  |                                           
  |.......                              |  19% [data_structure]                
  |                                           
  |........                             |  21%                                 
  |                                           
  |.........                            |  24% [missing_profile]               

  |                                           
  |..........                           |  26%                                 
  |                                           
  |...........                          |  29% [univariate_distribution_header]
  |                                           
  |...........                          |  31%                                 
  |                                           
  |............                         |  33% [plot_histogram]                

  |                                           
  |.............                        |  36%                                 
  |                                           
  |..............                       |  38% [plot_density]                  
  |                                           
  |...............                      |  40%                                 
  |                                           
  |................                     |  43% [plot_frequency_bar]            

  |                                           
  |.................                    |  45%                                 
  |                                           
  |..................                   |  48% [plot_response_bar]             
  |                                           
  |..................                   |  50%                                 
  |                                           
  |...................                  |  52% [plot_with_bar]                 
  |                                           
  |....................                 |  55%                                 
  |                                           
  |.....................                |  57% [plot_normal_qq]                

  |                                           
  |......................               |  60%                                 
  |                                           
  |.......................              |  62% [plot_response_qq]              
  |                                           
  |........................             |  64%                                 
  |                                           
  |.........................            |  67% [plot_by_qq]                    
  |                                           
  |..........................           |  69%                                 
  |                                           
  |..........................           |  71% [correlation_analysis]          

  |                                           
  |...........................          |  74%                                 
  |                                           
  |............................         |  76% [principal_component_analysis]  

  |                                           
  |.............................        |  79%                                 
  |                                           
  |..............................       |  81% [bivariate_distribution_header] 
  |                                           
  |...............................      |  83%                                 
  |                                           
  |................................     |  86% [plot_response_boxplot]         
  |                                           
  |.................................    |  88%                                 
  |                                           
  |.................................    |  90% [plot_by_boxplot]               
  |                                           
  |..................................   |  93%                                 
  |                                           
  |...................................  |  95% [plot_response_scatterplot]     
  |                                           
  |.................................... |  98%                                 
  |                                           
  |.....................................| 100% [plot_by_scatterplot]           
                                                                                                                           
output file: C:/Users/ploma/Desktop/estadistica_descriptiva/report.knit.md
"C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/pandoc" +RTS -K512m -RTS "C:\Users\ploma\Desktop\estadistica_descriptiva\report.knit.md" --to html4 --from markdown+autolink_bare_uris+tex_math_single_backslash --output pandoc1b6c31e627e1.html --lua-filter "C:\Users\ploma\AppData\Local\R\win-library\4.4\rmarkdown\rmarkdown\lua\pagebreak.lua" --lua-filter "C:\Users\ploma\AppData\Local\R\win-library\4.4\rmarkdown\rmarkdown\lua\latex-div.lua" --embed-resources --standalone --variable bs3=TRUE --section-divs --table-of-contents --toc-depth 6 --template "C:\Users\ploma\AppData\Local\R\win-library\4.4\rmarkdown\rmd\h\default.html" --no-highlight --variable highlightjs=1 --variable theme=yeti --mathjax --variable "mathjax-url=https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" --include-in-header "C:\Users\ploma\AppData\Local\Temp\RtmpOKn9us\rmarkdown-str1b6c6abf6102.html" 

Output created: report.html

Análisi univariada automàtica: compareGroups.

compareGroups és un paquet de R dissenyat per crear taules descriptives comparatives d’una manera clara i rigorosa. És ideal per a estudis mèdics i epidemiològics, ja que resumeix variables contínues i categòriques per grups, i hi afegeix proves estadístiques automàtiques (com t-test, chi-quadrat o ANOVA). La seva funció principal, compareGroups(), permet especificar una variable estratificadora i genera resums amb createTable(), exportables a Word, LaTeX o HTML. És molt útil per preparar la taula 1 d’un article científic, amb p-valors i estadístics ben formats. És potent, flexible i fàcil d’integrar en fluxos reproductibles. Exporta de forma sencilla la taula creada a word, excel, html o pdf. Tambe te capacitats de grafics resum com DataExplorer. Recomano molt aquest paquet. Un manual complert el podeu consultar aqui.

library(compareGroups)
Warning: el paquet 'compareGroups' es va construir amb la versió d'R 4.4.3
# Creem la taula comparativa
taulacomp <- compareGroups(Survived ~ ., data = titanic)
Warning in compareGroups.fit(X = X, y = y, include.label = include.label, :
Variables 'Name', 'Ticket', 'Cabin' have been removed since some errors
occurred
# plot(taulacomp)

# Mostrem la taula
taula <- createTable(taulacomp, show.all = T)
taula

--------Summary descriptives table by 'Survived'---------

_________________________________________________________ 
               [ALL]         0           1      p.overall 
               N=891       N=549       N=342              
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 
PassengerId  446 (257)   447 (261)   444 (252)    0.880   
Pclass      2.31 (0.84) 2.53 (0.74) 1.95 (0.86)  <0.001   
Sex:                                             <0.001   
    female  314 (35.2%) 81 (14.8%)  233 (68.1%)           
    male    577 (64.8%) 468 (85.2%) 109 (31.9%)           
Age         29.7 (14.5) 30.6 (14.2) 28.3 (15.0)   0.041   
SibSp       0.52 (1.10) 0.55 (1.29) 0.47 (0.71)   0.233   
Parch       0.38 (0.81) 0.33 (0.82) 0.46 (0.77)   0.013   
Fare        30.6 (41.1) 22.1 (31.4) 44.2 (50.3)  <0.001   
Embarked:                                        <0.001   
             2 (0.22%)   0 (0.00%)   2 (0.58%)            
    C       168 (18.9%) 75 (13.7%)  93 (27.2%)            
    Q       77 (8.64%)  47 (8.56%)  30 (8.77%)            
    S       644 (72.3%) 427 (77.8%) 217 (63.5%)           
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ 

Exercicis

  1. Crea un projecte d’R per aquests exercicis amb el nom “Exercicis_R_2”. Posa les preguntes com a comentaris en un script i a sota la solució amb codi. Intenta resoldre tot amb el material dels apunts o fent servir la ajuda de R o Google. Com a ultim recurs el chatGPT.
  2. Instala el paquet “medicaldata” i importa un dataset assignant-li un nom triat per tu al objecte
  3. Fes una inspecció de les dades incloent una análisi de missings (NA).
  4. Treu els outliers de l’edat del Titanic i torna a fer el boxplot
  5. Compara el preu del billet per sexe de forma gràfica.
  6. Fes un histograma de l’alçada dels personatges d’Starwars
  7. Selecciona les columnes de nom i massa d’Starwars i ordena per veure qui és el més gros.
  8. Compara gràficament i numericament el pes dels personatges per sexe.
  9. Inspecciona el dataset iris, obtén la llista de variables i busca informació sobre què són.
  10. Fes servir chatgpt per fer una gràfica molona amb aspecte per publicar del dataset iris.
  11. Del arxiu datos_originales, analitzar la existència de outliers graficament i despres crear un objecte sense outliers i comparar les gràfiques.
  12. Carrega unes dades de ST i aplica tots els punts d’aquest capitol, primer manualment i despres de forma automàtica. Fes un parell de gràfics avançats.