Manipulación de datos con R
Este documento es parte del curso Introducción a la programación en R
para Ciencias Sociales
Introducción
En esta práctica trabajaremos con el conjunto de datos IMDB Top 250 dataset french. Utiliza el siguiente código para descargarla en tu computadora:
Ejercicio 0
Importa el archivo que acabamos de descargar usando la función read.csv()
. Verifica la ubicación de tu directorio de trabajo y modificalo si es necesario.
Ejercicio 1
Inspecciona el contenido de la base de datos IMDB usando la función glimpse()
contenida en la librería tidyverse
. Esta función puede ser muy útil para tener una visión panorámica sobre la estructura de nuestros datos.
Ejercicio 2
Identifica al menos 4 problemas en la base de datos que deberían resolverse para poder hacer un ejercicio de análisis. Nota que hasta este momento no necesariamente sabemos como resolver los problemas.
Rows: 250
Columns: 13
$ X <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
$ Name <chr> "Shoah", "Home", "Untouchable", "Le Trou", "The Man Who…
$ Rank <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, …
$ Year <chr> "-1985", "(I) (2009)", "-2011", "-1960", "-1987", "-194…
$ Type <chr> "PG", "U", "15", "A", "", "A", "15", "15", "A", "U", "U…
$ Duration <chr> "566 min", "118 min", "112 min", "131 min", "30 min", "…
$ Genre <chr> "Documentary, History, War", "Documentary", "Biography,…
$ Rating <dbl> 8.7, 8.5, 8.5, 8.5, 8.5, 8.3, 8.3, 8.3, 8.2, 8.2, 8.2, …
$ MetaScore <int> 99, 47, 57, NA, NA, 96, 69, 80, NA, NA, NA, 86, 99, NA,…
$ Desc <chr> "Claude Lanzmann's epic documentary recounts the story …
$ Director_Stars <chr> "Director:\nClaude Lanzmann\n | \n S…
$ Votes <chr> "9,984", "", "", "", "", "", "", "", "", "", "", "", ""…
$ Gross <chr> "$0.02M", "", "", "", "", "", "", "", "", "", "", "", "…
Ejercicio 2.1
La variable Year
no es de tipo numeric
y contien algunos caractéres que no deberían estar ahí p.ej. “-”, “()”, “(I)”, etc. Aquí vamos a corregir ese problema:
Existen otras alternativas para corregir los problemas con la variable Year
. Por ejemplo, podemos usar expresiones regulares para describir patrones en las cadenas de texto ( strings ). Revisa la cheatsheet
sobre el uso de expresiones regulares usando el paquete {stringr}
en este enlace.
Solución con expresiones regulares
Puedes consultar una cheatsheet sobre el uso de expresiones regulares con el paquete stringr
en este Enlace.
Explicación detallada
El código anterior gsub("[^0-9]+","", Year)
utiliza la función gsub()
para buscar un patrón y realizar una sustitución en la cadena de texto guardada en la variable Year
.
Argumentos de la función gsub()
:
"[^0-9]+"
: Este es un patrón de expresión regular que significa “cualquier cosa que no sea un número del 0 al 9. Nota que el+
significa que puede haber uno o más de estos caractéres no numéricos.- El símbolo
^
dentro de los corchetes indica una negación. +
: Significa “uno o más de estos caracteres no numéricos”. Esto asegura que se eliminen grupos consecutivos de caracteres no numéricos.""
: Esto significa que estamos reemplazando los caracteres que coinciden con el patrón anterior (cualquier cosa que no sea un número), con una cadena vacía. En otras palabras, los eliminamos.
Ejercicio 2.2
La variable Type
o clasificación de la película contiene valores que no están codificados como perdidos sino que son espacios en blanco generados usando ""
.
Para codificar correctamente los datos perdidos podemos usar el siguiente código:
Supongamos que además de codificar las variables queremos descartar las observaciones con valores perdidos i.e., NA
. Para tal propósito podemos complementar el código anterior con las siguientes líneas:
Ejercicio 2.3
La variable Genre
no esta representada de forma útil. Debemos convertirla en una variable categórica o dummy. Nota que la forma en que se clasifican las películas se traslapa (i.e. "Drama, Mystery, Thriller"
).
Para solucionar este problema, primero vamos a convertir la variable Genre
en una variable categórica. Para tal propósito, vamos a usar la función case_when()
para clasificar el contenido de la variable Genre
en categorías generales:
library(dplyr)
library(stringr)
# Veamos cuatas categorías únicas hay en la variable Genre
unique(IMDB$Genre)
# Recodificamos la clasificación en categorías generales
IMDB2 <- IMDB2 %>%
mutate(Genre_Cat = case_when(
str_detect(Genre, "Action") ~ "Action", # ~ Asigna el valor
str_detect(Genre, "Comedy") ~ "Comedy",
str_detect(Genre, "Drama") ~ "Drama",
str_detect(Genre, "Horror") ~ "Horror",
str_detect(Genre, "Sci-Fi") ~ "Sci-Fi",
str_detect(Genre, "Thriller") ~ "Thriller",
str_detect(Genre, "Animation") ~ "Animation",
TRUE ~ "Other" # Todas las otras categorías
),
Genre_Cat = factor(Genre_Cat)
)
unique(IMDB2$Genre_Cat) #Revisamos el resultado
str(IMDB2$Genre_Cat) # ¿Qué tipo de datos tenemos?
Ejercicio 2.4
La variable Director_Stars
está almacenando realmente dos variables Director
y Stars
. Asimismo, contiene los strings Director:
y Stars:
. Debemos separar esta variable en dos nuevas columnas en nuestra base de datos y eliminar las palabras sobrantes.
Para este propósito podemos usar la función separte_wider_delim()
. Esta funcion requiere que definamos primero que símbolo se está usando para delimitar las dos variables en cuestión. (Nota: el separador es : |
. La expresion \n
es un caracter que implica un salto de línea. )
# Observamos las características de la variable
IMDB2$Director_Stars[1:10]
# Limpiamos y separamos los datos
IMDB2 <- IMDB2 %>%
mutate(
# Removemos \n (separador de líneas)
Director_Stars = gsub("\n", " ", Director_Stars)
# Removemos el espacio excesivo
%>% str_squish()
) %>%
# Separamos las columnas usando como delimitador el símbolo "|"
separate_wider_delim(Director_Stars, delim = " | ", names = c("Director", "Stars")) %>%
mutate(
# Rmovemos las etiquetas de las columnas
Director = str_remove(Director, "Director:\\s*"),
Stars = str_remove(Stars, "Stars:\\s*")
)
# Usamos \\s* como comodín de espacios en blanco
# Resultado
View(IMDB2)
Ejercicio 2.5
La variable Duration
mide la duración de cada película en minutos. Sin embargo, nota que los datos contienen el valor numérico y el string min
en la misma celda. Necesitamos generar una nueva variable numerica
que nos permita ordenar las películas de acuerdo a su duración en orden ascendente.
Ejercicio 3
En este ejercicio vamos a crear una tabla que nos muestre, por cada década, los promedio de la variable Rating
. Para tal propósito, primero vamos a crear una nueva variable denominada decade
usando condicionales. Después, vamos a calcular el promedio de la variable Rating
agrupando los valores usando group_by()
para cada década. Asegurate de que la tabla ordene los valores promedio de rating
en orden descendente.
Solución:
IMDB2 %>%
# Creamos una variable que indique la década
mutate(decade = case_when(
Year %in% c(1950:1959) ~ "50s",
Year %in% c(1960:1969) ~ "60s",
Year %in% c(1970:1979) ~ "70s",
Year %in% c(1980:1989) ~ "80s",
Year %in% c(1990:1999) ~ "90s",
Year %in% c(2000:2009) ~ "2000s",
Year %in% c(2010:2019) ~ "2010s",
Year %in% c(2019:2029) ~ "2020s",
.default = "40s or older")) %>%
# Creamos una tabla con los valores del rating por década
group_by(decade) %>%
summarise(avg_rating = mean(Rating)) %>%
arrange(-avg_rating) # Ordenamos de mayor a menor