Capítol 8 Resumenes de agregados

R tiene muchas opciones para construir agregados.

8.1 Summary

Para tener una primera impresión sobre los datos utiliza summary().

paises07Summ <- paises07
paises07Summ$pais <- as.character(paises07Summ$pais)
paises07Summ$fecha <- as.Date(paste(paises07Summ$anio,"12","31",sep="-"),"%Y-%m-%d")
paises07Summ$es_grande <- paises07Summ$poblacion > 30*10^6
paises07Summ$pib_per_capita[c(34,70,108)] <- NA

kable(summary(paises07Summ[,c("pais","continente","pib_per_capita","es_grande","fecha"),]))
pais continente pib_per_capita es_grande fecha
Length:142 África :52 Min. : 277.6 Mode :logical Min. :2007-12-31
Class :character Américas:25 1st Qu.: 1708.3 FALSE:106 1st Qu.:2007-12-31
Mode :character Asia :33 Median : 6223.4 TRUE :36 Median :2007-12-31
NA Europa :30 Mean :11750.2 NA Mean :2007-12-31
NA Oceanía : 2 3rd Qu.:18008.7 NA 3rd Qu.:2007-12-31
NA NA Max. :49357.2 NA Max. :2007-12-31
NA NA NA’s :3 NA NA

summary en factor y logic devuelve una tabla de frecuencias, en cambio en character no. En numericy Date devuelve 6 estadísticos básicos de resumen más el conteo de NAs.

8.1.1 Estadísticos basicos

Los 6 estadísticos básicos del summary son:

min(paises07Summ$pib_per_capita, na.rm=TRUE)
## [1] 277.5519
quantile(paises07Summ$pib_per_capita, 0.25, na.rm=TRUE)
##      25% 
## 1708.268
median(paises07Summ$pib_per_capita, na.rm=TRUE)
## [1] 6223.367
mean(paises07Summ$pib_per_capita, na.rm=TRUE)
## [1] 11750.22
quantile(paises07Summ$pib_per_capita, 0.75, na.rm=TRUE)
##      75% 
## 18008.73
max(paises07Summ$pib_per_capita, na.rm=TRUE)
## [1] 49357.19

El parámetro na.rm=TRUE evita que las funciones resumen, devuelvan un NA debido a la presencia de NA s en la variable pib_por_capita. Observa como esto sucede en la siguiente función.

mean(paises07Summ$pib_per_capita)
## [1] NA

La función quantile(), por sí sola, puede calcular todos los valores, excepto la media.

kable(quantile(paises07Summ$pib_per_capita, seq(0,1,1/4), na.rm=TRUE))
x
0% 277.5519
25% 1708.2679
50% 6223.3675
75% 18008.7268
100% 49357.1902

8.2 Tablas de frecuencias

Para obtener una tabla de frecuencias, utiliza table(). Para una variable.

kable(table(paises07Summ$continente))  # una variable
Var1 Freq
África 52
Américas 25
Asia 33
Europa 30
Oceanía 2

Tablas cruzadas de dos o más variables.

kable(table(paises07Summ$continente,paises07Summ$es_grande))
FALSE TRUE
África 42 10
Américas 19 6
Asia 20 13
Europa 23 7
Oceanía 2 0

Asia es el continente con mayor número de países grandes (de más de 30M de hab.).

En muchas ocasiones, es útil tramar las variables numéricas en intervalos. En R utiliza cut().

Vamos a crear la variable nivel de riqueza a partir del pib_per_capita cortando la variable por 1700$ y 18000$.

paises07Summ$nivel_de_riqueza <- cut(paises07Summ$pib_per_capita, 
                                         breaks=c(-Inf,1700,18000,Inf))
kable(head(paises07Summ[,c("pais","pib_per_capita","nivel_de_riqueza")]))

Para definir los breaks, R permite utilizar -Inf e Inf (infinito) como si fueran números.

cut() crea un factor ordenado a partir de la variable numeric con los siguientes levels:

levels(paises07Summ$nivel_de_riqueza)
## [1] "(-Inf,1.7e+03]"    "(1.7e+03,1.8e+04]" "(1.8e+04, Inf]"

Para modificar las etiquetas utiliza la misma función levels().

levels(paises07Summ$nivel_de_riqueza) <- c("Pobres","Medios","Ricos")

Mostramos a continuación la distribución de países ricos y pobres por continente en 2007.

kable(table(paises07Summ$continente, paises07Summ$nivel_de_riqueza, useNA = "ifany"))
Pobres Medios Ricos NA
África 29 22 0 1
Américas 1 20 4 0
Asia 4 18 10 1
Europa 0 9 20 1
Oceanía 0 0 2 0

Gráficamente.

ggplot(paises07Summ) +
  geom_bar(aes(x=continente, fill=nivel_de_riqueza), position = "fill") +
  labs(y="%")

Para calcular la tabla de porcentajes que se observan en el gráfico se utiliza prop.table(., margin = ?), dónde ? vale 1 para obtener el % fila y 2 para el % columna.

Para incluir la suma marginal por filas se utiliza addmargins(.,margin = ?), dónde ? vale 1 para incluir el total suma marginal fila y 2 para el total columna.

tabla1 <- table(paises07Summ$continente, paises07Summ$nivel_de_riqueza, useNA = "ifany")
tabla1 <- addmargins(tabla1, margin = 1) # total marginal columna (antes que el %)
tabla1 <- 100 * prop.table(tabla1, margin = 1)  # porcentaje fila
tabla1 <- addmargins(tabla1, margin = 2) # total marginal fila 
kable(tabla1,digits = 1)
Pobres Medios Ricos NA Sum
África 55.8 42.3 0.0 1.9 100
Américas 4.0 80.0 16.0 0.0 100
Asia 12.1 54.5 30.3 3.0 100
Europa 0.0 30.0 66.7 3.3 100
Oceanía 0.0 0.0 100.0 0.0 100
Sum 23.9 48.6 25.4 2.1 100

Observa que para definir el nivel de riqueza de los países en 2007 se ha realizado la siguiente transformación:

paises07$nivel_de_riqueza <- cut(paises07$pib_per_capita, breaks=c(-Inf,1700,18000,Inf))
levels(paises07$nivel_de_riqueza) <- c("Pobres","Medios","Ricos")

8.3 Agregados por subgrupos

Además de frecuencias, es necesario saber calcular otros estadísticos básicos para subgrupo de un data frame. Por ejemplo, la media de esperanza de vida y del pib per cápita, así como, el total de población por continente y nivel de riqueza.

agg1 <- aggregate(paises07[,c("esperanza_de_vida","pib_per_capita")],
                  list(continente = paises07$continente
                       , nivel_de_riqueza=paises07$nivel_de_riqueza),mean)
agg2 <- aggregate(paises07[,c("poblacion"),drop=FALSE],
                  list(continente = paises07$continente
                       , nivel_de_riqueza=paises07$nivel_de_riqueza),sum)

<recuerda>aggregate() permite calcular un mismo estadístico sobre varias variables segmentando por más de un eje.</recuerda>

Se juntan ahora los dos agregados con merge() y se genera la variable combinada continente_riqueza.

agg3 <- merge(agg1,agg2)
agg3$continente_riqueza <- paste(agg3$continente,agg3$nivel_de_riqueza,sep="-")

kable(agg3)
continente nivel_de_riqueza esperanza_de_vida pib_per_capita poblacion continente_riqueza
África Medios 59.06305 6014.4232 454062366 África-Medios
África Pobres 51.68423 943.7462 475477326 África-Pobres
Américas Medios 73.59135 7863.3024 550839183 Américas-Medios
Américas Pobres 60.91600 1201.6372 8502814 Américas-Pobres
Américas Ricos 76.86500 29152.0266 339529187 Américas-Ricos
Asia Medios 69.37822 4912.6469 3277982847 Asia-Medios
Asia Pobres 60.20820 1198.8519 282303757 Asia-Pobres
Asia Ricos 78.41910 31718.7983 251667223 Asia-Ricos
Europa Medios 74.26544 10264.4946 162756836 Europa-Medios
Europa Ricos 79.09852 31393.0475 423341693 Europa-Ricos
Oceanía Ricos 80.71950 29810.1883 24549947 Oceanía-Ricos

El mismo gráfico visto para países, ahora, agregado a nivel de continente y riqueza.

ggplot(agg3, aes(x=pib_per_capita
                          , y=esperanza_de_vida
                          , label=continente_riqueza
                          , color =continente
                          , size=poblacion)) +
  geom_point() +
  geom_label_repel(size=3, force=10) +
  scale_x_log10() +
  labs(title="Continentes-riqueza en 2007 (no ponderado)")
Contienentes (Fuente: Elaboración propia, datos de Gapminder)

Figura 8.1: Contienentes (Fuente: Elaboración propia, datos de Gapminder)

8.4 La familia apply

Como se ha comentado, las funciones apply permiten vectorizar las operaciones de forma eficiente, sin utilizar bucles for().

tapply

Es una alternativa a aggregate() para aplicar una función de agregación sobre una única variable y segmentando por un único eje.

tapply(paises07$esperanza_de_vida,paises07$continente,quantile,probs=0.25)
##   África Américas     Asia   Europa  Oceanía 
## 47.83400 71.75200 65.48300 75.02975 80.46175

lapply

Permite aplicar una función sobre cada elemento de un vector o lista. Devuelve una lista.

lapply(paises07[,-1], function(x) summary(x))
## $continente
##   África Américas     Asia   Europa  Oceanía 
##       52       25       33       30        2 
## 
## $anio
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2007    2007    2007    2007    2007    2007 
## 
## $esperanza_de_vida
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   39.61   57.16   71.94   67.01   76.41   82.60 
## 
## $poblacion
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 1.996e+05 4.508e+06 1.052e+07 4.402e+07 3.121e+07 1.319e+09 
## 
## $pib_per_capita
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   277.6  1624.8  6124.4 11680.1 18008.8 49357.2 
## 
## $nivel_de_riqueza
## Pobres Medios  Ricos 
##     36     69     37

sapply

Misma funcionalidad que lapply, pero simplificando el resultado a vector cuando es posible.

sapply(paises07, function(x) class(x))
##              pais        continente              anio esperanza_de_vida 
##          "factor"          "factor"         "integer"         "numeric" 
##         poblacion    pib_per_capita  nivel_de_riqueza 
##         "integer"         "numeric"          "factor"

apply

Calcula agregados sobre cada una de los vectores marginas fila (MARGIN = 1), alternativamente columna (MARGIN = 2) de una matriz.

a <- matrix(1:10,ncol=2)
apply(a,MARGIN = 1,sum)
## [1]  7  9 11 13 15

Columnas,

a <- matrix(1:10,ncol=2)
apply(a,2,sum)
## [1] 15 40