gapminderEn esta demo usaremos el conjunto de datos gapminder
disponible en el paquete con el mismo nombre. Usaremos la función
install.packages() para instalar el paquete y luego la
función library() para cargarlo a R.
## install.packages("gapminder")
library(gapminder)
Una vez instalado y cargado el paquete, podemos acceder al conjunto
de datos gapminder y su documentación usando las funciones
data() y help().
data("gapminder")
## help(gapminder)
La última línea de código deberá mostrar la documentación en el panel
de ayuda si estas desde RStudio. Si estas desde la consola de
R, se deberá abrir una página web en tu navegador
predeterminado.
Según la descripción de la documentación, este conjunto de datos contiene información sobre la esperanza de vida, el PIB (producto interno bruto) per cápita y la población por país. Éste es un data frame con 1704 observaciones (renglones) y 6 variables (columnas). La siguiente tabla contiene una descripción de las variables que componen al conjunto de datos. Esta fue extraida directamente de la documentación.
| Variable | Descripción |
|---|---|
country |
país: factor con 142 categorías |
continent |
continente: factor con 5 categorías |
year |
año: de 1952 a 2007 en incrementos de 5 años |
lifeExp |
esperanza de vida al nacer, en años |
pop |
población |
gpdPercap |
PIB per cápita (dólares americanos) |
Visualicemos ahora el conjunto de datos. Para esto podemos usar las
funciones str(), summary(), y/o
head(). Usemos las tres para ver que información
proporciona cada una de ellas.
str()The función str() muestra la estructura
interna del objeto que le pasemos. En este caso, la estructura de
gapminder
str(gapminder)
## tibble [1,704 × 6] (S3: tbl_df/tbl/data.frame)
## $ country : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
## $ lifeExp : num [1:1704] 28.8 30.3 32 34 36.1 ...
## $ pop : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
## $ gdpPercap: num [1:1704] 779 821 853 836 740 ...
Al inicio nos dice que gapminder es un
tibble y no un data.frame. Los
tibbles son versiones modificadas de los data frames. Son
especialmente útiles cuando tenemos un conjunto de datos enorme. Por
ahora, imaginemos que son lo mismo.
A un lado de la palabra tibble, nos muestra
[1,704 x 6]. Esto nos indica el tamaño (o dimensión) del
conjunto de datos. Este conjunto tiene 1704 observaciones y 6 variables.
Puedes obtener el mismo resultado ejecutando
dim(gapminder).
A partir de la segunda línea, nos muestra una descripción breve de
cada variable. El signo $ indica variable. La
primera variable es country que es de tipo factor con 142
categorías que empiezan con “Afghanistan”. Los valores después de
: indican los valores que son almacenados. Al ser ésta una
variable de tipo factor, las categorías son alamacenadas como números
(con etiqueta). En este caso, los 1’s indicarían la categoría
“Afghanistan”. Los tres puntos (…) indican que la lista de valores
continua.
De manera similar, podemos extraer información de las otras
variables, como, por ejemplo, year que es una variable
entera (int) con 1704 valores. Sus primeros valores son
1952, 1957, 1692, ….
Por último, de aquí podemos deducir el tipo de variable que es cada
una. country y continent son variables
categóricas (factor en R) y las restantes son
variables numéricas (numeric o integer en
R).
summary()Otra función que nos ayuda a visualizar el conjunto de datos de
manera resumida es summary() (resumen en inglés). Veamos
que nos dice
summary(gapminder)
## country continent year lifeExp
## Afghanistan: 12 Africa :624 Min. :1952 Min. :23.60
## Albania : 12 Americas:300 1st Qu.:1966 1st Qu.:48.20
## Algeria : 12 Asia :396 Median :1980 Median :60.71
## Angola : 12 Europe :360 Mean :1980 Mean :59.47
## Argentina : 12 Oceania : 24 3rd Qu.:1993 3rd Qu.:70.85
## Australia : 12 Max. :2007 Max. :82.60
## (Other) :1632
## pop gdpPercap
## Min. :6.001e+04 Min. : 241.2
## 1st Qu.:2.794e+06 1st Qu.: 1202.1
## Median :7.024e+06 Median : 3531.8
## Mean :2.960e+07 Mean : 7215.3
## 3rd Qu.:1.959e+07 3rd Qu.: 9325.5
## Max. :1.319e+09 Max. :113523.1
##
En el caso se las variables categóricas, como country y
continent, nos muestra las diferentes categorías y un
conteo de cada una de éstas. Esto es, en la variable
continent, la categoría Africa aparece 624 veces, Americas
300, Asia 396, Europe 360 y Oceania 24 veces.
Para las variables numéricas como year,
lifeExp, pop y gdpPercap,
summary() nos muestra la media, los tres cuartiles y los
valores mínimo y máximo. Por ejemplo, el PIB per capita
(gpdPercap) mínimo registrado es 241.2 y el máximo
registrado es 113523.1.
No te asustes con los valores que aparecen en la variable
pop, es notación científica, o sea, 6.001e+04
es lo mismo que \(6.001\times10^4=60,010\) y
1.319e+09 es igual a \(1.319\times10^9=1,319,000,000\).
head()Por último, veamos la función head(). Ésta nos muestra
la primera porción del conjunto de datos. Podemos especificarle cuantas
observaciones queremos visualizar con el argumento n.
Nota: tail() hace lo mismo pero con la
última porción del conjunto de datos.
head(gapminder, n = 8)
En el caso en el que el conjuto de datos sea un tibble
nos mostrará, abajo del nombre de la variable, el tipo de variable. Por
ejemplo, lifeExp es de tipo <dbl>, que
es “sinónimo” de numeric. Debajo de country
aparece <fctr> lo que significa factor.
Seguido de esto, aparecerán las observaciones. La primera observación es
(Afganistan, Asia, 1952, 28.801, 8425333, 779.4453), que se puede leer
como: en el país de Afganistan del continente de Asia en el año
1952, la esperanza de vida era de 28.801 años, la población de 8,425,333
habitantes con un PIB per cápita de 779.4453 dólares
americanos.
Cuando se quiere usar un conjunto de datos para hacer cualquier tipo
de análisis estadístico el primer paso casi siempre es limpiar el
conjunto de datos. Es decir, buscar los datos faltantes
(NAs o cadenas vacías "") o datos incorrectos.
También es común darle el formato adecuado a las variables.
is.na()Empecemos por buscar si hay datos faltantes o valores
NA. La función is.na() evalua los elementos de
un objeto en R, por ejemplo, un data frame o tibble, y
regresa TRUE o FALSE si el elemento es
NA o no, respectivamente. Por ejemplo,
x = c(1,2,3,NA,4,5,NA)
is.na(x)
## [1] FALSE FALSE FALSE TRUE FALSE FALSE TRUE
La función regresó TRUE en las posiciones 4 y 7 del
vector y FALSE para las restantes pues en en el vector
x, los elementos 4 y 7 son NAs.
En nuestro caso, solo nos interesa saber si hay algún (any en inglés)
valor NA en gapminder, por lo que combinando
estas dos funciones podríamos contestar a esta pregunta
any(is.na(gapminder)) # leelo como ¿algún valor es NA en gapminder?
## [1] FALSE
¡Que bien! No hay ningún NA. Peeero, este no es el único
tipo de valor faltante. Veamos el segundo, las cadenas vacías.
which()Para comparar dos valores (numéricos o caracteres) específicos
debemos usar operadores lógicos: == para la igualdad,
> , <, >=,
<=, o != para la diferencia. Veamos como
funciona ==
x = c("A","B","C","","","D")
x == ""
## [1] FALSE FALSE FALSE TRUE TRUE FALSE
== comparará uno a uno los valores de x con
la cadena vacía "" y regresará TRUE si son
idénticas o FALSE si no lo son. En este caso, regresa
TRUE en la posición 4 y 5, que coinciden perfectamente con
la posición de las cadenas vacías en x, y regresa
FALSE en las posiciones restantes pues no son cadenas
vacías.
De nuevo, no estamos interesados en saber las posiciones de las
cadenas vacías, por ahora, por lo que sería suficiente con usar
any() en combinación con los operadores lógicos para saber
si hay alguna cadena vacía de gapminder
any(gapminder == "") # Leelo como ¿Hay algún valor en gapminder igual a "")
## [1] FALSE
¡Fiuuuu! Tampoco hay cadenas vacías. Peeeero, si las hubiera, nos
interesaría saber la posiciones de tales cadenas vacías. Aquí es donde
entra la función which()
x = c("A","B","C","","","D")
which(x == "")
## [1] 4 5
Esta nos regresa la posición de las cadenas vacías en x,
justamente la 4ta y 5ta. ¿Qué pasará si lo aplicamos a nuestro conjunto
de datos?
which(gapminder == "")
## integer(0)
¿No esperabas que regresara alguna posición o sí? Al no haber cadenas
vacías en gapminder, ésta regresa integer(0),
o sea, no hay posición que regresar.
unique()Ok, parece no haber datos faltantes, y a juzgar por el resumen que obtuvimos previamente, no parece haber datos incorrectos.
summary(gapminder)
## country continent year lifeExp
## Afghanistan: 12 Africa :624 Min. :1952 Min. :23.60
## Albania : 12 Americas:300 1st Qu.:1966 1st Qu.:48.20
## Algeria : 12 Asia :396 Median :1980 Median :60.71
## Angola : 12 Europe :360 Mean :1980 Mean :59.47
## Argentina : 12 Oceania : 24 3rd Qu.:1993 3rd Qu.:70.85
## Australia : 12 Max. :2007 Max. :82.60
## (Other) :1632
## pop gdpPercap
## Min. :6.001e+04 Min. : 241.2
## 1st Qu.:2.794e+06 1st Qu.: 1202.1
## Median :7.024e+06 Median : 3531.8
## Mean :2.960e+07 Mean : 7215.3
## 3rd Qu.:1.959e+07 3rd Qu.: 9325.5
## Max. :1.319e+09 Max. :113523.1
##
Tal vez te preguntes, ¿cómo puedo saber si hay registros incorrectos?
La verdad es que no puedes, a menos que sean muy evidentes. Si, por
ejemplo, en el resumen del conjunto de datos, en la variable
pop el registro más pequeño, o sea el mínimo, es -45,
evidentemente hay un registro incorrecto pues no puede haber un país con
población negativa.
¿Qué hay de las variables categóricas? Tal vez alguna categoría esté mal escrita. Veamos las categorías distintas o únicas de cada variable categórica
unique(gapminder$continent)
## [1] Asia Europe Africa Americas Oceania
## Levels: Africa Americas Asia Europe Oceania
La función unique() nos regresa los nombre únicos que
aparecen en la variable continent del conjunto de datos.
Cuando la variable es tipo factor, como es el caso, también podemos usar
la función levels() para obtener las categorías.
levels(gapminder$continent)
## [1] "Africa" "Americas" "Asia" "Europe" "Oceania"
Incluso, podemos usar esta misma para cambiar el nombre de algunas categorías o “niveles” (de aquí el nombre de la función). Cambiemos la categoría “Americas” por “America”.
levels(gapminder$continent)[2] = "America"
levels(gapminder$continent)
## [1] "Africa" "America" "Asia" "Europe" "Oceania"
Así está mejor.
Ahora veamos las categorías de country
levels(gapminder$country)
## [1] "Afghanistan" "Albania"
## [3] "Algeria" "Angola"
## [5] "Argentina" "Australia"
## [7] "Austria" "Bahrain"
## [9] "Bangladesh" "Belgium"
## [11] "Benin" "Bolivia"
## [13] "Bosnia and Herzegovina" "Botswana"
## [15] "Brazil" "Bulgaria"
## [17] "Burkina Faso" "Burundi"
## [19] "Cambodia" "Cameroon"
## [21] "Canada" "Central African Republic"
## [23] "Chad" "Chile"
## [25] "China" "Colombia"
## [27] "Comoros" "Congo, Dem. Rep."
## [29] "Congo, Rep." "Costa Rica"
## [31] "Cote d'Ivoire" "Croatia"
## [33] "Cuba" "Czech Republic"
## [35] "Denmark" "Djibouti"
## [37] "Dominican Republic" "Ecuador"
## [39] "Egypt" "El Salvador"
## [41] "Equatorial Guinea" "Eritrea"
## [43] "Ethiopia" "Finland"
## [45] "France" "Gabon"
## [47] "Gambia" "Germany"
## [49] "Ghana" "Greece"
## [51] "Guatemala" "Guinea"
## [53] "Guinea-Bissau" "Haiti"
## [55] "Honduras" "Hong Kong, China"
## [57] "Hungary" "Iceland"
## [59] "India" "Indonesia"
## [61] "Iran" "Iraq"
## [63] "Ireland" "Israel"
## [65] "Italy" "Jamaica"
## [67] "Japan" "Jordan"
## [69] "Kenya" "Korea, Dem. Rep."
## [71] "Korea, Rep." "Kuwait"
## [73] "Lebanon" "Lesotho"
## [75] "Liberia" "Libya"
## [77] "Madagascar" "Malawi"
## [79] "Malaysia" "Mali"
## [81] "Mauritania" "Mauritius"
## [83] "Mexico" "Mongolia"
## [85] "Montenegro" "Morocco"
## [87] "Mozambique" "Myanmar"
## [89] "Namibia" "Nepal"
## [91] "Netherlands" "New Zealand"
## [93] "Nicaragua" "Niger"
## [95] "Nigeria" "Norway"
## [97] "Oman" "Pakistan"
## [99] "Panama" "Paraguay"
## [101] "Peru" "Philippines"
## [103] "Poland" "Portugal"
## [105] "Puerto Rico" "Reunion"
## [107] "Romania" "Rwanda"
## [109] "Sao Tome and Principe" "Saudi Arabia"
## [111] "Senegal" "Serbia"
## [113] "Sierra Leone" "Singapore"
## [115] "Slovak Republic" "Slovenia"
## [117] "Somalia" "South Africa"
## [119] "Spain" "Sri Lanka"
## [121] "Sudan" "Swaziland"
## [123] "Sweden" "Switzerland"
## [125] "Syria" "Taiwan"
## [127] "Tanzania" "Thailand"
## [129] "Togo" "Trinidad and Tobago"
## [131] "Tunisia" "Turkey"
## [133] "Uganda" "United Kingdom"
## [135] "United States" "Uruguay"
## [137] "Venezuela" "Vietnam"
## [139] "West Bank and Gaza" "Yemen, Rep."
## [141] "Zambia" "Zimbabwe"
Esas son muchas, enfoquemonos en solo una de ellas.
levels(gapminder$country)[c(28,29,56,70,71,140)]
## [1] "Congo, Dem. Rep." "Congo, Rep." "Hong Kong, China" "Korea, Dem. Rep."
## [5] "Korea, Rep." "Yemen, Rep."
Tal vez te pregustes porque esas en específico. Bueno, la única razón es porque no me gustan esas comas que aparecen allí, así que vamos a cambiarlas.
levels(gapminder$country)[c(28,29,56,70,71,140)] =
c("Congo-Kinshasa","Congo-Brazzaville","Hong Kong",
"North Korea", "South Korea", "Yemen")
levels(gapminder$country)[c(28,29,56,70,71,140)]
## [1] "Congo-Kinshasa" "Congo-Brazzaville" "Hong Kong"
## [4] "North Korea" "South Korea" "Yemen"
Aquí sobre la elección de los nombres para “Congo, Dem. Rep.” y “Congo, Rep.” y acá para los nombres de “Korea, Dem. Rep.” y “Korea, Rep.”.
Ya que nuestro conjunto está “limpio”, quiza querramos guardarlo para
la próxima vez que lo usemos. Lo podemos guardar como un archivo .csv
con la funcion write.csv().
write.csv()Esta función toma muchos argumentos, pero dos son necesarios:
x: el nombre del objeto que queremos guardar
file: el nombre del archivo en el que lo queremos
guardar con extensión incluida
write.csv(gapminder, "gapminder.csv")
Hay algunos argumentos que tal vez quieras usar dentro de la función
write.csv() como row.names y
col.names. Busca en la documentación que hacen estos
argumentos.
Puedes encontrar el archivo .Rmd en mi repositorio bajo el nombre ManipulacionGapminder.Rmd en Github.