Programación Básica en R Studio - Estructura de Datos
Creación de datos ordenados
La ordenación de datos es un proceso fundamental en el análisis de datos, y en
R, podemos llevarlo a cabo de manera coherente utilizando el paquetetidyr, que forma parte del ecosistematidyverse. Al trabajar contidyr, podemos seguir tres reglas clave para asegurar que nuestros conjuntos de datos estén correctamente organizados.En primer lugar, cada variable debe tener su propia columna. En segundo lugar, cada observación debe tener su propia fila y, por último, cada valor debe tener su propia celda. Esto se ilustrado por el diagrama siguiente.
Segundo, una estructura de datos consistente es muy importante. Los paquetes que forman parte de tidyverse incluyendo
dplyryggplot2están diseñados para trabajar con datos ordenados, así que asegurar que que tus datos sean uniformes facilita el procesamiento eficiente de tus datos. Además, colocar las variables en columnas permite facilitar la vectorización enR.
Frecuentemente, al trabajar con conjuntos de datos, nos encontraremos con que estos no están organizados según los principios de los datos ordenados. Esta falta de orden puede deberse a diversas razones, y una de las más comunes es la falta de familiaridad de quienes crearon el conjunto de datos con los principios de organización de datos.
Las razones detrás de la desorganización de los datos pueden ser variadas. En muchos casos, las personas que recopilan o generan los datos pueden no estar al tanto de la importancia de organizarlos de manera adecuada. Pueden haber centrado su atención en la recolección de datos sin considerar la estructura final que estos deberían tener para su análisis posterior.
Además, la complejidad de algunos conjuntos de datos puede dificultar su organización. Al trabajar con grandes volúmenes de datos o datos provenientes de múltiples fuentes, puede resultar desafiante mantener una estructura ordenada y coherente. Esto puede llevar a conjuntos de datos desordenados que requieren trabajo adicional para su limpieza y organización.
El primer paso es averiguar cuáles son las variables y observaciones del conjunto de datos. Esto le facilitará la comprensión de lo que deben ser las columnas y las. Además, también tendrá que resolver uno o dos problemas comunes. Tendrá que averiguar si una variable está repartida en varias columnas, y si una observación está dispersa en varias filas. Estos conceptos se conocen como reunión y dispersión. Examinaremos examinaremos más a fondo estos conceptos en los ejercicios de este capítulo
En este capítulo trataremos los siguientes temas:
- Recopilación
- Distribución
- Separación
- Unión
Recopilación
Un problema común en muchos conjuntos de datos es que los nombres de
las columnas no son variables sino valores de una variable. En la figura
siguiente, las columnas 1999 y 2000 son en realidad valores de la
variable YEAR. Cada fila de la tabla existente representa
en realidad dos observaciones. El paquete tidyr puede
utilizarse para reunir estas columnas existentes en una nueva variable.
En este caso, tenemos que crear una nueva columna columna llamada
YEAR y luego reunir en esta los valores existentes en las
columnas 1999 y 2000.
La función gather() del paquete tidyr es la
idonea para la reestrucutración del df por ejemplo
gather("1999", "2000", key = "year", value = "cases")
Hay tres parámetros de la función gather(). 1) El conjunto de
columnas que representan lo que deberían ser valores y no variables.
Estas serían las columnas 1999 y 2000. 2) Nombrar la variable de la
nueva columna. Esto también se llama la clave key, y en
este caso será la variable del año. 3) Por último, tendrás que
proporcionar el valor value, que es el nombre de la
variable cuyos valores se reparten por las celdas.
Practiquemos lo anterior con el
siguiente ejercicio. como primera media descargue el archivo
CountryPopulation.csv localizado en
Bases-de-datos.
abra el archivo en una hoja de excel solo para visualizarlo, si realiza
alguna modificación procure no guardarla.
Las columnas de cada año representan valores, no variables. Estas
columnas deben reunirse en un nuevo par de variables que representen el
año y la población. En este ejercicio utilizarás la función
gather() para realizar esta tarea de ordenación de
datos.
Carguemos el df en nuestro entorno
## Rows: 264 Columns: 10
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Country Name, Country Code
## dbl (8): 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
| Country Name | Country Code | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 |
|---|---|---|---|---|---|---|---|---|---|
| Aruba | ABW | 101669 | 102053 | 102577 | 103187 | 103795 | 104341 | 104822 | 105264 |
| Afghanistan | AFG | 28803167 | 29708599 | 30696958 | 31731688 | 32758020 | 33736494 | 34656032 | 35530081 |
| Angola | AGO | 23369131 | 24218565 | 25096150 | 25998340 | 26920466 | 27859305 | 28813463 | 29784193 |
| Albania | ALB | 2913021 | 2905195 | 2900401 | 2895092 | 2889104 | 2880703 | 2876101 | 2873457 |
| Andorra | AND | 84449 | 83751 | 82431 | 80788 | 79223 | 78014 | 77281 | 76965 |
| Arab World | ARB | 356508908 | 364895878 | 373306993 | 381702086 | 390043028 | 398304960 | 406452690 | 414491886 |
| United Arab Emirates | ARE | 8270684 | 8672475 | 8900453 | 9006263 | 9070867 | 9154302 | 9269612 | 9400145 |
| Argentina | ARG | 41223889 | 41656879 | 42096739 | 42539925 | 42981515 | 43417765 | 43847430 | 44271041 |
| Armenia | ARM | 2877311 | 2875581 | 2881922 | 2893509 | 2906220 | 2916950 | 2924816 | 2930450 |
| American Samoa | ASM | 55637 | 55320 | 55230 | 55307 | 55437 | 55537 | 55599 | 55641 |
| Antigua and Barbuda | ATG | 94661 | 95719 | 96777 | 97824 | 98875 | 99923 | 100963 | 102012 |
| Australia | AUS | 22031750 | 22340024 | 22742475 | 23145901 | 23504138 | 23850784 | 24210809 | 24598933 |
| Austria | AUT | 8363404 | 8391643 | 8429991 | 8479823 | 8546356 | 8642699 | 8736668 | 8809212 |
| Azerbaijan | AZE | 9054332 | 9173082 | 9295784 | 9416801 | 9535079 | 9649341 | 9757812 | 9862429 |
| Burundi | BDI | 8766930 | 9043508 | 9319710 | 9600186 | 9891790 | 10199270 | 10524117 | 10864245 |
Ahora utilice la función gather() para reestructurar el
df de la siguiente forma
dfPop2 = gather(dfPop,
"2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017",
key = "YEAR",
value = "POPULATION")
knitr::kable(head(dfPop2, 10))| Country Name | Country Code | YEAR | POPULATION |
|---|---|---|---|
| Aruba | ABW | 2010 | 101669 |
| Afghanistan | AFG | 2010 | 28803167 |
| Angola | AGO | 2010 | 23369131 |
| Albania | ALB | 2010 | 2913021 |
| Andorra | AND | 2010 | 84449 |
| Arab World | ARB | 2010 | 356508908 |
| United Arab Emirates | ARE | 2010 | 8270684 |
| Argentina | ARG | 2010 | 41223889 |
| Armenia | ARM | 2010 | 2877311 |
| American Samoa | ASM | 2010 | 55637 |
¿que sucedería, si en un caso hipotético nos encontramos con un gran número de columna de este tipo? Para ello, la opción mas eficiente sería
years <- colnames(dfPop)[grep("^\\d{4}$", colnames(dfPop))]
dfPop3 <- dfPop %>%
gather(key = "YEAR", value = "POPULATION", all_of(years))
knitr::kable(head(dfPop3, 10))| Country Name | Country Code | YEAR | POPULATION |
|---|---|---|---|
| Aruba | ABW | 2010 | 101669 |
| Afghanistan | AFG | 2010 | 28803167 |
| Angola | AGO | 2010 | 23369131 |
| Albania | ALB | 2010 | 2913021 |
| Andorra | AND | 2010 | 84449 |
| Arab World | ARB | 2010 | 356508908 |
| United Arab Emirates | ARE | 2010 | 8270684 |
| Argentina | ARG | 2010 | 41223889 |
| Armenia | ARM | 2010 | 2877311 |
| American Samoa | ASM | 2010 | 55637 |
Donde, en expresiones regulares, "^\\d{4}$" tiene el
siguiente significado:
^: Representa el inicio de una cadena.\\d: Representa un dígito.{4}: Indica que el elemento anterior (\\d, en este caso) debe aparecer exactamente 4 veces.$: Representa el final de una cadena.
En resumen, "^\\d{4}$" coincide con cualquier cadena que
contenga exactamente 4 dígitos y no contenga ningún otro carácter
adicional antes o después de los dígitos.
Distribución
La distribución es lo contrario de la recopilación y se utiliza cuando una observación se distribuye en varias filas. En el diagrama siguiente, la tabla debe definir una observación de un país por año. Sin embargo, observará que está repartida en dos filas. Una fila para cases y otra para population.
Para ello, la función spread() soluciona este problema.
La función spread() toma dos parámetros: la columna que
contiene los nombres de las variables repetidas, conocida como
key y una columna que contiene valores de múltiples
variables, que llamamos value
Cargue el conjunto de datos DSR Ubicado aquí
llamadado table2 con extensión .rdata
utilizando el código que ve a continuación escribiendo en el panel de la
consola.
| country | year | key | value |
|---|---|---|---|
| Afghanistan | 1999 | cases | 745 |
| Afghanistan | 1999 | population | 19987071 |
| Afghanistan | 2000 | cases | 2666 |
| Afghanistan | 2000 | population | 20595360 |
| Brazil | 1999 | cases | 37737 |
Utilice la función spread() para corregir este problema.
Recuerde instalar el paquete
| country | year | cases | population |
|---|---|---|---|
| Afghanistan | 1999 | 745 | 19987071 |
| Afghanistan | 2000 | 2666 | 20595360 |
| Brazil | 1999 | 37737 | 172006362 |
| Brazil | 2000 | 80488 | 174504898 |
| China | 1999 | 212258 | 1272915272 |
| China | 2000 | 213766 | 1280428583 |
Separación
Otro caso común es el de dos variables que se colocan en la misma columna. Por ejemplo, la hoja de cálculo siguiente tiene una columna State-County Name que en realidad contiene dos variables separadas por una barra.
La función separate() puede utilizarse para dividir una columna en varias columnas dividiendo por un separador. Por defecto, la función separate() buscará automáticamente cualquier carácter no alfanumérico o se puede definir un carácter específico
En la carpeta de base-de-datos hay un archivo llamado usco2005.csv. Descargue y abra este archivo, por ejemplo con Microsoft Excel, o algún otro tipo de software de hoja de cálculo, posterior a ello carguela en el entorno de esta forma
## Rows: 3222 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): STATE, State-County Name
## dbl (4): STATEFIPS, COUNTYFIPS, FIPS, TP-TotPop
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
| STATE | STATEFIPS | COUNTYFIPS | FIPS | State-County Name | TP-TotPop |
|---|---|---|---|---|---|
| AL | 1 | 1 | 1001 | Alabama-Autauga County | 48.612 |
| AL | 1 | 3 | 1003 | Alabama-Baldwin County | 162.586 |
| AL | 1 | 5 | 1005 | Alabama-Barbour County | 28.414 |
| AL | 1 | 7 | 1007 | Alabama-Bibb County | 21.516 |
| AL | 1 | 9 | 1009 | Alabama-Blount County | 55.725 |
| AL | 1 | 11 | 1011 | Alabama-Bullock County | 11.055 |
| AL | 1 | 13 | 1013 | Alabama-Butler County | 20.766 |
| AL | 1 | 15 | 1015 | Alabama-Calhoun County | 112.141 |
| AL | 1 | 17 | 1017 | Alabama-Chambers County | 35.460 |
| AL | 1 | 19 | 1019 | Alabama-Cherokee County | 24.522 |
Utilice la función separate() para separar el contenido de la columna State-County Name en las columnas StateAbbrev y CountyName
## Warning: Expected 2 pieces. Additional pieces discarded in 3222 rows [1, 2, 3, 4, 5, 6,
## 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
| STATE | STATEFIPS | COUNTYFIPS | FIPS | StateAbbrev | CountyName | TP-TotPop |
|---|---|---|---|---|---|---|
| AL | 1 | 1 | 1001 | Alabama | Autauga | 48.612 |
| AL | 1 | 3 | 1003 | Alabama | Baldwin | 162.586 |
| AL | 1 | 5 | 1005 | Alabama | Barbour | 28.414 |
| AL | 1 | 7 | 1007 | Alabama | Bibb | 21.516 |
| AL | 1 | 9 | 1009 | Alabama | Blount | 55.725 |
| AL | 1 | 11 | 1011 | Alabama | Bullock | 11.055 |
| AL | 1 | 13 | 1013 | Alabama | Butler | 20.766 |
| AL | 1 | 15 | 1015 | Alabama | Calhoun | 112.141 |
| AL | 1 | 17 | 1017 | Alabama | Chambers | 35.460 |
| AL | 1 | 19 | 1019 | Alabama | Cherokee | 24.522 |
Unión
La función unite() es exactamente lo contrario de
separate(), ya que combina varias columnas en una sola.
Aunque no se utiliza tan a menudo como separate(), puede
haber ocasiones en las que necesite la funcionalidad proporcionada por
unite(). La idea de este ejercicio es que se una el
df separado anteriormente
En el panel de la consola, añada el código que ve a continuación para
unir las columnas StateAbbrev y CountyName en una sola columna.
Por defecto unite() realiza unión con base en la expresión
regular "_",
"unite(data, col, ..., sep = "_", remove = TRUE)"
| STATE | STATEFIPS | COUNTYFIPS | FIPS | State_County_Name | TP-TotPop |
|---|---|---|---|---|---|
| AL | 1 | 1 | 1001 | Alabama_Autauga | 48.612 |
| AL | 1 | 3 | 1003 | Alabama_Baldwin | 162.586 |
| AL | 1 | 5 | 1005 | Alabama_Barbour | 28.414 |
| AL | 1 | 7 | 1007 | Alabama_Bibb | 21.516 |
| AL | 1 | 9 | 1009 | Alabama_Blount | 55.725 |
| AL | 1 | 11 | 1011 | Alabama_Bullock | 11.055 |
| AL | 1 | 13 | 1013 | Alabama_Butler | 20.766 |
| AL | 1 | 15 | 1015 | Alabama_Calhoun | 112.141 |
| AL | 1 | 17 | 1017 | Alabama_Chambers | 35.460 |
| AL | 1 | 19 | 1019 | Alabama_Cherokee | 24.522 |