El Tidyverse es un conjunto de paquetes integrados para el lenguaje de programación R, diseñados con el objetivo de facilitar el análisis de datos de manera estructurada, legible y eficiente. Su filosofía se basa en el concepto de “datos ordenados” (tidy data), donde cada variable es una columna, cada observación una fila, y cada tipo de unidad observacional forma una tabla.
Estos paquetes comparten principios de diseño comunes y una gramática coherente, lo que permite a los usuarios aprender un conjunto de reglas aplicables en todo el ecosistema, aumentando así la productividad y la claridad del código.
Paquetes de tidyverse
Definición
Un data frame es una estructura de datos clave en estadística y en R.
Fuentes de datos en R
Los conjuntos de datos de gran tamaño, generalmente almacenados como
data frames en R, suelen provenir de
archivos externos.
Existen múltiples tipos de archivos que pueden importarse, entre
ellos:
csv,
txt, html y json.
El ecosistema Tidyverse ofrece funciones que permiten importar y gestionar estas diversas fuentes de datos de manera sencilla y eficiente.
readr de tidyverselibrary(tidyverse)
# CSV con punto decimal y encabezados
StudyArea <- read_csv("RDataSets/RDataSets/StudyArea.csv")
Antes de realizar un análisis de datos en R, con
frecuencia es necesario manipular o transformar la información de
distintas formas.
Para ello, el paquete dplyr, que hace parte del
ecosistema tidyverse, ofrece un conjunto de funciones
que facilitan la transformación y manejo de datos de manera eficiente y
estructurada.
En esta sección abordaremos los siguientes aspectos fundamentales:
dplyrlibrary(tidyverse)
StudyArea %>%
filter(TOTALACRES >= 25000)
StudyArea %>%
filter(TOTALACRES >= 1000,YEAR_== 2016)
&.StudyArea %>%
filter(TOTALACRES >= 1000 & YEAR_== 2016)
StudyArea %>%
filter(YEAR_ %in% c(2010, 2011, 2012))
select()Continuando con el ejemplo de las incendios forestales
FIRENAME,
TOTALACRES, YEAR_StudyArea %>%
select(FIRENAME, TOTALACRES, YEAR_)
FIRENAME,
TOTALACRES, YEAR_, cambian el nombre de
TOTALACRES por ACRES y YEAR_ por
YR.StudyArea %>%
select("FIRE" = "FIRENAME", "ACRES" ="TOTALACRES", "YR" = "YEAR_")
DATEStudyArea %>%
select(contains("DATE"))
DATE y
también inicien con TOTALStudyArea %>%
select(contains("DATE"),starts_with("TOTAL"))
Continuando con el ejemplo de los incendios forestales
FIRENAME, TOTALACRES,
YEAR_ y renombralas NAME, ACRES,
YR, respectivamente. Finalmente, ordena ACRES
de forma ascendente y muestrame las 5 ultimas.StudyArea %>%
filter(TOTALACRES >= 1000, YEAR_ == 2016) %>%
select("NAME" = "FIRENAME", "ACRES" = "TOTALACRES", "YR" = "YEAR_") %>%
arrange(ACRES) %>%
tail(n=5)
## # A tibble: 5 × 3
## NAME ACRES YR
## <chr> <dbl> <dbl>
## 1 Cedar 45977 2016
## 2 Erskine 48007 2016
## 3 Range 12 171915 2016
## 4 Junkins 181320 2016
## 5 PIONEER 188404 2016
FIRENAME, TOTALACRES,
YEAR_ y renombralas NAME, ACRES,
YR, respectivamente. Finalmente, ordena ACRES
de forma descendente y muestrame las 5 primeras.StudyArea %>%
filter(TOTALACRES >= 2000, YEAR_ == 2016) %>%
select("NAME" = "FIRENAME", "ACRES" = "TOTALACRES", "YR" = "YEAR_") %>% arrange(desc(ACRES)) %>%
head(n=5)
## # A tibble: 5 × 3
## NAME ACRES YR
## <chr> <dbl> <dbl>
## 1 PIONEER 188404 2016
## 2 Junkins 181320 2016
## 3 Range 12 171915 2016
## 4 Erskine 48007 2016
## 5 Cedar 45977 2016
mutateContinuando con el ejemplo de los incendios forestales
Carguemos nuevamente los datos
StudyArea %>%
select(ORGANIZATI, STATE, YEAR_, TOTALACRES, CAUSE, STARTDATED) %>%
filter(TOTALACRES >= 1000 & CAUSE %in% c("Human", "Natural")) %>%
mutate(DOY = yday(as.Date(STARTDATED, format="%m/%d/%y%H:%M"))) -> df_sol
# Vista rápida
knitr::kable(head(df_sol))
| ORGANIZATI | STATE | YEAR_ | TOTALACRES | CAUSE | STARTDATED | DOY |
|---|---|---|---|---|---|---|
| FWS | Arizona | 1988 | 1500 | Human | 3/26/88 0:00 | 86 |
| FWS | Arizona | 1986 | 10390 | Human | 5/15/86 0:00 | 135 |
| FWS | Montana | 1986 | 1400 | Human | 6/27/86 0:00 | 178 |
| FWS | Arizona | 2002 | 1035 | Human | 2/28/02 0:00 | 59 |
| FWS | Arizona | 2000 | 5700 | Human | 4/9/00 0:00 | 100 |
| FWS | Arizona | 2000 | 2750 | Human | 5/14/00 0:00 | 135 |
Continuando con el ejemplo de incendios forestales
StudyArea %>%
select(ORGANIZATI, STATE, YEAR_, TOTALACRES, CAUSE) %>%
filter(TOTALACRES >= 1000) %>%
mutate(DECADE = ifelse(YEAR_ %in% 1980:1989, "1980-1989",
ifelse(YEAR_ %in% 1990:1999, "1990-1999",
ifelse(YEAR_ %in% 2000:2009, "2000-2009",
ifelse(YEAR_ %in% 2010:2016, "2010-2016", "-99"))))) %>%
group_by(DECADE) %>%
summarise(media_acres = mean(TOTALACRES),
ds_acres = sd(TOTALACRES),
mediana_acres = median(TOTALACRES),
RIC_acres = IQR(TOTALACRES),
min_acres = min(TOTALACRES),
max_acres = max(TOTALACRES),
q1_acres = quantile(TOTALACRES)[2],
q3_acres = quantile(TOTALACRES)[4]) -> df_sol_2
# Vista rápida
knitr::kable(head(df_sol_2))
| DECADE | media_acres | ds_acres | mediana_acres | RIC_acres | min_acres | max_acres | q1_acres | q3_acres |
|---|---|---|---|---|---|---|---|---|
| 1980-1989 | 8128.645 | 23681.53 | 2887.5 | 5074.50 | 1000 | 427680.0 | 1543.25 | 6617.75 |
| 1990-1999 | 8333.036 | 18212.44 | 2925.0 | 5641.80 | 1000 | 231389.0 | 1545.00 | 7186.80 |
| 2000-2009 | 12329.181 | 30156.35 | 3653.5 | 7859.75 | 1000 | 590620.0 | 1803.00 | 9662.75 |
| 2010-2016 | 14443.197 | 39272.14 | 3926.0 | 8552.00 | 1000 | 558198.3 | 1782.00 | 10334.00 |
Ejercicio 1 para entregar
df_idaho <- StudyArea %>%
filter(STATE == "Idaho")
df_idaho <- StudyArea %>%
filter(STATE == "Idaho") %>%
select(YEAR_, CAUSE, TOTALACRES) %>%
rename(
year = YEAR_,
cause = CAUSE,
total_acres = TOTALACRES
)
summary_idaho <- df_idaho %>%
group_by(cause, year) %>%
summarise(acres_burned = sum(total_acres, na.rm = TRUE)) %>%
ungroup()
## `summarise()` has grouped output by 'cause'. You can override using the
## `.groups` argument.
head(summary_idaho)
## # A tibble: 6 × 3
## cause year acres_burned
## <chr> <dbl> <dbl>
## 1 Human 1980 71975.
## 2 Human 1981 219362.
## 3 Human 1982 34016.
## 4 Human 1983 48242.
## 5 Human 1984 36838.
## 6 Human 1985 68035.
df_clean <- summary_idaho %>%
filter(cause %in% c("Human", "Natural"))
ggplot(df_clean, aes(x = year, y = acres_burned / 1000000, color = cause)) +
geom_line(linewidth = 1) +
labs(
title = "Evolución de Acres Quemados en Idaho",
subtitle = "Comparación entre causas Human y Natural",
x = "Año",
y = "Millones de Acres Quemados",
color = "Causa"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14),
legend.position = "top"
)
La ordenación de datos es una forma coherente de organizar los datos
en R y puede facilitarse a través del paquete tidyr que se
encuentra en el ecosistema tidyverse.
Hay tres reglas que podemos seguir para hacer un conjunto de datos
ordenado:
A continuación, tendrás que 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 (year). Por último,
tendrás que proporcionar el valor value, que es el
nombre de la variable cuyos valores se reparten por las
celdas.
Carguemos los datos
library(tidyverse)
df <- read_csv("RDataSets/RDataSets/CountryPopulation.csv")
head(df,n=5)
## # A tibble: 5 × 10
## `Country Name` `Country Code` `2010` `2011` `2012` `2013` `2014` `2015` `2016`
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Aruba ABW 1.02e5 1.02e5 1.03e5 1.03e5 1.04e5 1.04e5 1.05e5
## 2 Afghanistan AFG 2.88e7 2.97e7 3.07e7 3.17e7 3.28e7 3.37e7 3.47e7
## 3 Angola AGO 2.34e7 2.42e7 2.51e7 2.60e7 2.69e7 2.79e7 2.88e7
## 4 Albania ALB 2.91e6 2.91e6 2.90e6 2.90e6 2.89e6 2.88e6 2.88e6
## 5 Andorra AND 8.44e4 8.38e4 8.24e4 8.08e4 7.92e4 7.80e4 7.73e4
## # ℹ 1 more variable: `2017` <dbl>
gather como se ve a
continuacióndf2 = gather(df,
"2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017",
key = "YEAR",
value = "POPULATION")
knitr::kable(head(df2, 5))
| 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 |
years <- colnames(df)[grep("^\\d{4}$", colnames(df))]
df2 <- df %>%
gather(key = "YEAR", value = "POPULATION", all_of(years))
knitr::kable(head(df2, 5))
| 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 |
table2:knitr::kable(head(table2))
| country | year | type | count |
|---|---|---|---|
| Afghanistan | 1999 | cases | 745 |
| Afghanistan | 1999 | population | 19987071 |
| Afghanistan | 2000 | cases | 2666 |
| Afghanistan | 2000 | population | 20595360 |
| Brazil | 1999 | cases | 37737 |
| Brazil | 1999 | population | 172006362 |
spread() para corregir este
problema.table2b = spread(table2, key = type, value = count)
knitr::kable(head(table2b))
| 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 |
df = read_csv("RDataSets/RDataSets/usco2005.csv")
knitr::kable(head(df, 5))
| 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 |
df2 = separate(df, "State-County Name",into = c("StateAbbrev", "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, ...].
knitr::kable(head(df2, 5))
## Warning in attr(x, "align"): 'xfun::attr()' está en desuso.
## Utilizar 'xfun::attr2()' en su lugar.
## Ver help("Deprecated")
## Warning in attr(x, "format"): 'xfun::attr()' está en desuso.
## Utilizar 'xfun::attr2()' en su lugar.
## Ver help("Deprecated")
| 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 |
df3 = unite(df2, State_County_Name, StateAbbrev, CountyName)
knitr::kable(head(df3, 5))
| 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 |