2.1. Manejo de Datos

RStudio provee una gran diversidad de recursos para el manejo y transformación de los datos

Los archivos que obtenemos de una base de datos o que generamos en nuestras investigaciones, usualmente contienen más datos de los que necesitamos para una exploración, visualización o análisis estadístico; en estos casos podemos seleccionar aquellos casos y/o variables que deseamos usando procedimientos de RStudio. En muchos casos, los datos requieren transformaciones, para cambiar unidades o escala. Otras manipulaciones que muchas veces queremos realizar, incluyen: eliminación de valores incorrectos, cambio de formato o estructura de los datos.

2.1.1. Manejo de datos usando dplyr y tidyr

Al finalizar esta sección podrás realizar diversas manipulaciones de los datos usando los paquetes dplyr y tidyr

Seleccionando columnas y filtrando filas

Usaremos el archivo de datos de muertes asociadas a COVID-19 en los Estados Unidos, obtenido del CDC (ver módulo anterior, tema 1.8.6), coviddata.csv. Vamos a eliminar columnas que no nos interesan: Data as of, Start Date y Footnote. Usaremos las funciones select y filter.

## activar paquetes a usar
library(readr)
library(dplyr)
## importar los datos a una variable
# usaremos un lector de datos .csv diferente, en readr
# crea un tibble, forma especial de data.frame
# produce una lista de las columnas y su tipo de dato
covid_19 <- read_csv("data/coviddata.csv")
str(covid_19)
## spec_tbl_df [57,834 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Data As Of                              : chr [1:57834] "06/16/2021" "06/16/2021" "06/16/2021" "06/16/2021" ...
##  $ Start Date                              : chr [1:57834] "01/01/2020" "01/01/2020" "01/01/2020" "01/01/2020" ...
##  $ End Date                                : chr [1:57834] "06/12/2021" "06/12/2021" "06/12/2021" "06/12/2021" ...
##  $ Group                                   : chr [1:57834] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year                                    : logi [1:57834] NA NA NA NA NA NA ...
##  $ Month                                   : logi [1:57834] NA NA NA NA NA NA ...
##  $ State                                   : chr [1:57834] "United States" "United States" "United States" "United States" ...
##  $ Sex                                     : chr [1:57834] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ Age Group                               : chr [1:57834] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ COVID-19 Deaths                         : num [1:57834] 590091 81 322 37 112 ...
##  $ Total Deaths                            : num [1:57834] 4791858 26746 46977 4859 7811 ...
##  $ Pneumonia Deaths                        : num [1:57834] 520776 288 773 156 222 ...
##  $ Pneumonia and COVID-19 Deaths           : num [1:57834] 289584 12 61 6 24 ...
##  $ Influenza Deaths                        : num [1:57834] 9161 21 183 64 77 ...
##  $ Pneumonia, Influenza, or COVID-19 Deaths: num [1:57834] 829164 378 1217 251 387 ...
##  $ Footnote                                : chr [1:57834] NA NA NA NA ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   `Data As Of` = col_character(),
##   ..   `Start Date` = col_character(),
##   ..   `End Date` = col_character(),
##   ..   Group = col_character(),
##   ..   Year = col_logical(),
##   ..   Month = col_logical(),
##   ..   State = col_character(),
##   ..   Sex = col_character(),
##   ..   `Age Group` = col_character(),
##   ..   `COVID-19 Deaths` = col_double(),
##   ..   `Total Deaths` = col_double(),
##   ..   `Pneumonia Deaths` = col_double(),
##   ..   `Pneumonia and COVID-19 Deaths` = col_double(),
##   ..   `Influenza Deaths` = col_double(),
##   ..   `Pneumonia, Influenza, or COVID-19 Deaths` = col_double(),
##   ..   Footnote = col_character()
##   .. )
# usaremos select para seleccionar las columnas que queremos
# son más las que queremos: - para eliminar las que no queremos
covid_select <- select(covid_19, -"Data As Of", -"Start Date", -Footnote)
str(covid_select)
## tibble [57,834 × 13] (S3: tbl_df/tbl/data.frame)
##  $ End Date                                : chr [1:57834] "06/12/2021" "06/12/2021" "06/12/2021" "06/12/2021" ...
##  $ Group                                   : chr [1:57834] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year                                    : logi [1:57834] NA NA NA NA NA NA ...
##  $ Month                                   : logi [1:57834] NA NA NA NA NA NA ...
##  $ State                                   : chr [1:57834] "United States" "United States" "United States" "United States" ...
##  $ Sex                                     : chr [1:57834] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ Age Group                               : chr [1:57834] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ COVID-19 Deaths                         : num [1:57834] 590091 81 322 37 112 ...
##  $ Total Deaths                            : num [1:57834] 4791858 26746 46977 4859 7811 ...
##  $ Pneumonia Deaths                        : num [1:57834] 520776 288 773 156 222 ...
##  $ Pneumonia and COVID-19 Deaths           : num [1:57834] 289584 12 61 6 24 ...
##  $ Influenza Deaths                        : num [1:57834] 9161 21 183 64 77 ...
##  $ Pneumonia, Influenza, or COVID-19 Deaths: num [1:57834] 829164 378 1217 251 387 ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...
# usaremos filter para quedarnos con los datos de Puerto Rico
covid_filter <- filter(covid_select, State == "Puerto Rico")
str(covid_filter)
## tibble [1,071 × 13] (S3: tbl_df/tbl/data.frame)
##  $ End Date                                : chr [1:1071] "06/12/2021" "06/12/2021" "06/12/2021" "06/12/2021" ...
##  $ Group                                   : chr [1:1071] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year                                    : logi [1:1071] NA NA NA NA NA NA ...
##  $ Month                                   : logi [1:1071] NA NA NA NA NA NA ...
##  $ State                                   : chr [1:1071] "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico" ...
##  $ Sex                                     : chr [1:1071] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ Age Group                               : chr [1:1071] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ COVID-19 Deaths                         : num [1:1071] 2433 0 NA 0 NA ...
##  $ Total Deaths                            : num [1:1071] 42308 184 282 29 29 ...
##  $ Pneumonia Deaths                        : num [1:1071] 6026 NA NA NA NA ...
##  $ Pneumonia and COVID-19 Deaths           : num [1:1071] 1719 0 NA 0 0 ...
##  $ Influenza Deaths                        : num [1:1071] 107 0 NA NA 0 0 NA NA NA 0 ...
##  $ Pneumonia, Influenza, or COVID-19 Deaths: num [1:1071] 6839 NA NA NA NA ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...


Uso de ‘pipes’

En el ejemplo anterior vemos que para llegar al objeto final, covid_filter, tuvimos que crear un paso intermedio, covid_select. En este caso no es muy importante, pero cuando se hacen múltiples manipulaciones y transformaciones, puede ser engorroso y fuente de errores. Una alternativa es usar lo que se conocen como ‘pipes’ para conectar los procedimientos y que los datos fluyan como en una tubería (pipe). El conector que se usa es: %>%; se puede generar usando: control + shift + M (en MacOS).

# creamos un nuevo objeto con los datos seleccionados y filtrados
# el archivo original covid_19 no se modifica
covid_PR <- covid_19 %>% 
  select(-"Data As Of", -"Start Date", -Footnote) %>% 
  filter(State == "Puerto Rico")
str(covid_PR)
## tibble [1,071 × 13] (S3: tbl_df/tbl/data.frame)
##  $ End Date                                : chr [1:1071] "06/12/2021" "06/12/2021" "06/12/2021" "06/12/2021" ...
##  $ Group                                   : chr [1:1071] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year                                    : logi [1:1071] NA NA NA NA NA NA ...
##  $ Month                                   : logi [1:1071] NA NA NA NA NA NA ...
##  $ State                                   : chr [1:1071] "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico" ...
##  $ Sex                                     : chr [1:1071] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ Age Group                               : chr [1:1071] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ COVID-19 Deaths                         : num [1:1071] 2433 0 NA 0 NA ...
##  $ Total Deaths                            : num [1:1071] 42308 184 282 29 29 ...
##  $ Pneumonia Deaths                        : num [1:1071] 6026 NA NA NA NA ...
##  $ Pneumonia and COVID-19 Deaths           : num [1:1071] 1719 0 NA 0 0 ...
##  $ Influenza Deaths                        : num [1:1071] 107 0 NA NA 0 0 NA NA NA 0 ...
##  $ Pneumonia, Influenza, or COVID-19 Deaths: num [1:1071] 6839 NA NA NA NA ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...

 

Home

Cambio de nombres de las columnas

Tenemos nombres de las columnas que son muy largos, y nos pueden crear errores en los análisis. Vamos a usar otra función de dplyr, llamada rename.

# producimos un nuevo tibble con los nuevos nombres
covid_PR_1 <- covid_PR %>% 
  rename(date = "End Date", state = State, sex = Sex, age = "Age Group", c_deaths = "COVID-19 Deaths", t_deaths = "Total Deaths", p_deaths = "Pneumonia Deaths", pc_deaths = "Pneumonia and COVID-19 Deaths", i_deaths = "Influenza Deaths", pic_deaths = "Pneumonia, Influenza, or COVID-19 Deaths")
str(covid_PR_1)
## tibble [1,071 × 13] (S3: tbl_df/tbl/data.frame)
##  $ date      : chr [1:1071] "06/12/2021" "06/12/2021" "06/12/2021" "06/12/2021" ...
##  $ Group     : chr [1:1071] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year      : logi [1:1071] NA NA NA NA NA NA ...
##  $ Month     : logi [1:1071] NA NA NA NA NA NA ...
##  $ state     : chr [1:1071] "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico" ...
##  $ sex       : chr [1:1071] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ age       : chr [1:1071] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ c_deaths  : num [1:1071] 2433 0 NA 0 NA ...
##  $ t_deaths  : num [1:1071] 42308 184 282 29 29 ...
##  $ p_deaths  : num [1:1071] 6026 NA NA NA NA ...
##  $ pc_deaths : num [1:1071] 1719 0 NA 0 0 ...
##  $ i_deaths  : num [1:1071] 107 0 NA NA 0 0 NA NA NA 0 ...
##  $ pic_deaths: num [1:1071] 6839 NA NA NA NA ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...


Transformación de datos

Vamos ahora a crear una nueva columna con el porcentaje de muertes por CoviD-19 del total de muertes a la fecha. Usaremos la función mutate.

# realizamos los cambios sobre el mismo tibble
covid_PR_1 <- covid_PR_1 %>%
  mutate(porc_ct = (c_deaths / t_deaths) * 100) %>%
  mutate(date = as.Date(date, format = "%m/%d/%Y"))
str(covid_PR_1)
## tibble [1,071 × 14] (S3: tbl_df/tbl/data.frame)
##  $ date      : Date[1:1071], format: "2021-06-12" "2021-06-12" ...
##  $ Group     : chr [1:1071] "By Total" "By Total" "By Total" "By Total" ...
##  $ Year      : logi [1:1071] NA NA NA NA NA NA ...
##  $ Month     : logi [1:1071] NA NA NA NA NA NA ...
##  $ state     : chr [1:1071] "Puerto Rico" "Puerto Rico" "Puerto Rico" "Puerto Rico" ...
##  $ sex       : chr [1:1071] "All Sexes" "All Sexes" "All Sexes" "All Sexes" ...
##  $ age       : chr [1:1071] "All Ages" "Under 1 year" "0-17 years" "1-4 years" ...
##  $ c_deaths  : num [1:1071] 2433 0 NA 0 NA ...
##  $ t_deaths  : num [1:1071] 42308 184 282 29 29 ...
##  $ p_deaths  : num [1:1071] 6026 NA NA NA NA ...
##  $ pc_deaths : num [1:1071] 1719 0 NA 0 0 ...
##  $ i_deaths  : num [1:1071] 107 0 NA NA 0 0 NA NA NA 0 ...
##  $ pic_deaths: num [1:1071] 6839 NA NA NA NA ...
##  $ porc_ct   : num [1:1071] 5.75 0 NA 0 NA ...
##  - attr(*, "problems")= tibble [99,144 × 5] (S3: tbl_df/tbl/data.frame)
##   ..$ row     : int [1:99144] 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 ...
##   ..$ col     : chr [1:99144] "Year" "Year" "Year" "Year" ...
##   ..$ expected: chr [1:99144] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
##   ..$ actual  : chr [1:99144] "2020" "2020" "2020" "2020" ...
##   ..$ file    : chr [1:99144] "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" "'data/coviddata.csv'" ...


Rearreglando datos para producir una tabla

De nuestro tibble podemos extraer algunos de los datos y rearreglarlos en forma de una tabla. Para esto usaremos una función del paquete tidyr: spread. Queremos extraer los datos de muertes por CoviD-19 (c_deaths) por sexo (sex) y grupo de edad (age). Antes debemos seleccionar las columnas de las cuales nos interesa obtener la información.

# activar tidyr
library(tidyr)
# uso de spread luego de select para expandir los datos por sexo
covid_sex <- covid_PR_1 %>%
  filter(Group == "By Month") %>%
  select(date, sex, age, c_deaths) %>%
  spread(sex, c_deaths)
head(covid_sex, 20)
## # A tibble: 20 x 5
##    date       age               `All Sexes` Female  Male
##    <date>     <chr>                   <dbl>  <dbl> <dbl>
##  1 2020-01-31 0-17 years                  0      0     0
##  2 2020-01-31 1-4 years                   0      0     0
##  3 2020-01-31 15-24 years                 0      0     0
##  4 2020-01-31 18-29 years                 0      0     0
##  5 2020-01-31 25-34 years                 0      0     0
##  6 2020-01-31 30-39 years                 0      0     0
##  7 2020-01-31 35-44 years                 0      0     0
##  8 2020-01-31 40-49 years                 0      0     0
##  9 2020-01-31 45-54 years                 0      0     0
## 10 2020-01-31 5-14 years                  0      0     0
## 11 2020-01-31 50-64 years                 0      0     0
## 12 2020-01-31 55-64 years                 0      0     0
## 13 2020-01-31 65-74 years                 0      0     0
## 14 2020-01-31 75-84 years                 0      0     0
## 15 2020-01-31 85 years and over           0      0     0
## 16 2020-01-31 All Ages                    0      0     0
## 17 2020-01-31 Under 1 year                0      0     0
## 18 2020-02-29 0-17 years                  0      0     0
## 19 2020-02-29 1-4 years                   0      0     0
## 20 2020-02-29 15-24 years                 0      0     0
# solo los totales de todas las edades por mes
covid_sex <- filter(covid_sex, age == "All Ages")
covid_sex
## # A tibble: 18 x 5
##    date       age      `All Sexes` Female  Male
##    <date>     <chr>          <dbl>  <dbl> <dbl>
##  1 2020-01-31 All Ages           0      0     0
##  2 2020-02-29 All Ages           0      0     0
##  3 2020-03-31 All Ages          21     10    11
##  4 2020-04-30 All Ages          78     31    47
##  5 2020-05-31 All Ages          35     15    20
##  6 2020-06-30 All Ages          16     NA    13
##  7 2020-07-31 All Ages          91     27    64
##  8 2020-08-31 All Ages         197     84   113
##  9 2020-09-30 All Ages         233     94   139
## 10 2020-10-31 All Ages         173     79    94
## 11 2020-11-30 All Ages         342    144   198
## 12 2020-12-31 All Ages         436    179   257
## 13 2021-01-31 All Ages         244    121   123
## 14 2021-02-28 All Ages         131     62    69
## 15 2021-03-31 All Ages          68     37    31
## 16 2021-04-30 All Ages         195     84   111
## 17 2021-05-31 All Ages         170     73    97
## 18 2021-06-12 All Ages          NA      0    NA


Guardar los resultados de las manipulaciones en un archivo externo

Una vez realizados los procedimientos anteriores, podemos estar interesado/as en usar el tibble final en un análisis en otro proyecto o en otro programa. Usando la función write_csv podemos crear un archivo .csv.

# vamos a guardar en un archivo el tibble covid_sex
write_csv(covid_sex, file = "data/covid-sex.csv")

 

Home