Tarea 2. ‘RMarkdown’, ‘Stringr’ y ‘Rebus’


Ejercicio 1

La sección práctica de la tercera clase del curso consistió en dar ejemplos para introducir el concepto de expresiones regulares. El código puede descargarse aquí.

A partir de dicho código, realice un tutorial explicando al menos tres de los ejemplos ahí presentados.


Tutorial: ¿Cómo modificar fechas?

Si existiera un tibble con fechas que no coinciden en formato, las funciones de los paquetes stringr y rebus pueden ayudarnos a homologarlas. Estos son los pasos para consegurlo.

Antes que todo hay que asegurarse que estén instalados los paquetes necesarios:

#Instalar paquetes

library(rebus)
library(tidyverse)
library(readxl)
library(rtweet)

A continuación mostarmos un ejemplo de tibble con el que trabajaremos

#Generamos un tibble (ejemplo)

fechas <- tribble(~Fechas, 
                  "01-01-2001", 
                  "Primero de Enero del 2001", 
                  "01/01/2001", 
                  "01 01 2001",
                  "01@01@2001",
                  "01_01_2001",
                  "01-Ene-2001")

Detectar y cambiar las palabras de y del, y los espacios

Gracias a regex en rebus podemos ver que las fechas no están homologadas.

Primero vamos a capturar nuestra expresión regular creando un patrón, que agregaremos a un objeto llamado pat. Esto lo logramos atrapando los espacios entre palabras con SPC.

#Selección de espacios, de y del usando`%R%` (coloquialmente lo llamamos pegamento) para atrapar las palabras. Luego, invertimos el proceso: `%R%` `SPC`.

pat <- SPC %R% or1(c("de", "del")) %R% SPC
str_view_all(fechas$Fechas,
             pattern = pat)
#Ejectutar el patrón que remplazará todo por guiones 

fechas$Fechas <- str_replace_all(fechas$Fechas,
                                 pattern = pat,
                                 replacement = "-")

Detectar y cambiar guiones, diagonales, espacios y arrobas**

El siguiente paso será utilizar un objeto en rebus llamado char_class, una funciónque sirve para definir un conjunto de caracteres que van a formar parte del patron. Es decir, todo los caracteres que contenga entre paréntesis van a ser seleccionados en el nuevo patrón.

Para ello debemos introducir los caracteres “-/@_” en dicha función y luego reemplazarlos por un guión “-”

#Función char_class
pat <- or1(char_class("-/@_", SPC)) 
str_view_all(fechas$Fechas,  
             pattern = pat)
#Ejecutar patrón que reemplazará todo por guiones

fechas$Fechas <- str_replace_all(fechas$Fechas, 
                pattern = pat, 
                replacement = "-")

fechas$Fechas
## [1] "01-01-2001"         "Primero-Enero-2001" "01-01-2001"        
## [4] "01-01-2001"         "01-01-2001"         "01-01-2001"        
## [7] "01-Ene-2001"
Igualar todas las fechas al formato %dd-%mm-%YYYY

En este último paso debemos utilizar una función de stringr str_remplace_all para reemplazar todas las palabras que falten por el mes que necesitamos (en este ejemplo “Enero” y “Primero” serán sustituidos por 01).

Nota: los cambios son escalonados, por lo cual, en el ejemplo “Enero” debe ir antes de “Ene”, de otra manera, “Ene” se sustuituirá como “01”, y “Enero” se convertirá en “01ro”, por lo cual no se realizaría el cambio esperado.

str_replace_all(fechas$Fechas, c("Primero" = "01",
                                 "Enero" = "01",
                                 "Ene" = "01"))
## [1] "01-01-2001" "01-01-2001" "01-01-2001" "01-01-2001" "01-01-2001"
## [6] "01-01-2001" "01-01-2001"

Gracias por seguir este tutorial

“No olvides que los formatos de fecha son diferentes dependiendo de la región…”

JuveYell


Ejercicio 2

Repaso teórico de procesaminto de texto (Clase 02 y 03).

  1. ¿Para qué sirve la librería stringr?

Es un paquete de la familia Tidyverse para trabajar cadenas de texto, que son las variables tipo character. Posee características importantes que nos permiten crear patrones y modificar las cadenas de muchas formas.

Las cadenas no son componentes glamorosos y de alto perfil de R, pero juegan un papel importante en muchas tareas de limpieza y preparación de datos. El paquete stringr proporciona un conjunto cohesivo de funciones diseñadas para hacer que trabajar con cadenas sea lo más fácil posible. – Sitio web de stringr

  1. ¿Qué son y para qué sirven las expresiones regulares?

En programación, no sólo R si no otros algunos lenguajes de programación, contamos con una herramienta muy poderosa conocida como redex (regular expressions) o expresiones regulares

Son secuencias de caracteres para definir un patrón de búsqueda. Las expresiones regulares sirven tanto para quedarnos con palabras/frases importantes, así como para deshacernos de ellas.

Son como la “navaja suiza” para trabajar con datos de texto, es una inversión de tiempo que todo analista tiene que hacer. – Juvenal Campos

  1. ¿Para qué sirve la librería rebus?

En R existe este paquete que nos facilita el poder utilizar estas herramientas de captura de texto, ya que tiene una librería {rebus} que es como una interfaz que nos permite convertir texto un poco más legible a esas expresiones regulares. Más detalles

  1. ¿Para qué sirve la función str_view() y str_view_all()? ¿Cuál es la diferencia entre ambas?

str_view() Atrapa la primera ocurrencia del patrón. str_view_all() Atrapa todas las ocurrencias del patrón.

La diferencia es que str_vie wmuestra la primera coincidencia y str_view_allmuestra todas.

  1. ¿Para qué sirve la funcion str_detect() ystr_detect_all()? ¿Cuál es la diferencia entre ambas?

str_detect() Detecta cadenas de texto que incluyen un patrón en particular *Es muy útil para filtrar

str_detect_all() No vimos esta función en clase, pero en este sitio web dice que “devuelve un vector lógico con resultados de Stri_detect () para cada patrón en el segundo vector de caracteres de parámetros”.

  1. ¿Para que sirve la función str_replace() y str_replace_all()? ¿Cuál es la diferencia entre ambas?

str_replace() Busca patrones que estan en una cadena de texto y los replaza por otro nuestro

str_replace_all() Reemplaza todos los patrones coincidentes en cada cadena de texto

  1. ¿Para que sirve la función str_remove() y str_remove_all()? ¿Cuál es la diferencia entre ambas?

str_remove() Remueve la primera coincidencia de un patrón

str_remove_all() Remueve TODAS las coincidencias de un patrón

La primera funciona con la primera coincidencia y la segunda para todo el texto.

  1. ¿Para que sirve la función str_extract() y str_extract_all()? ¿Cuál es la diferencia entre ambas?

str_extract() Extrae patrones de una cadena de texto str_extract_all() Extrae patrones de una cadena de texto de cada coincidencia del patrón

La primera función se detiene en la primera coincidencia y la segunda aplica a toda la cadena de texto.


Ejercicio 3

Práctica stringr + rebus (Clase 02 y 03)

Estas son las librerías que utilizaremos en la sección práctica. Cárgalas o instalalas en caso de que no las tengas instaladas en tu computadora.

# Librerias
library(tidyverse)
library(rebus)
library(htmltools)

Dados los siguientes numeros de telefono guardados en numeros, limpie los datos de tal forma que todos los numeros tengan el mismo formato. Para esto, utilice expresiones regulares y funciones de stringr.

(Sugerencia: El formato puede ser el que usted defina, pero el mas facil es que sean solo los numeros, sin símbolos raros).

numeros <- c("(595)107-3344",
"(890)-123-4465",
"999 107 5243",
"999_989-0756")

Vamos a limpiar el tibble numeros. Para ello crearemos nuestra expresión regular creando un patrón, que agregaremos a un objeto llamado telefono.

# 2. Generamos una regex que capture todos los numeros contenidos entre paréntesis, guiones bajos y cortos y Espacios

telefono <- char_class("-/_()", SPC) 
str_view_all(numeros, pattern = telefono) 
# Remover todos los elementos que señale el patrón que ya hicimos

numeros <- str_remove_all(string = numeros, pattern = telefono)

#Al reemplazar el objeto numeros, tenemos el resultado que queríamos.

#Comprobación:
numeros
## [1] "5951073344" "8901234465" "9991075243" "9999890756"

Ejercicio 04.

Práctica con bases de datos. (Clase 02 y 03)

La siguiente base de datos contiene tweets publicados tras el estreno de la pelicula " Joker (2019)".

  1. Lea la base de datos con el siguiente código:
library(tidyverse)
library(rebus)
bd <-
read_csv("https://raw.githubusercontent.com/JuveCampos/miniProyectos/master/elJokerWordCloud/db.csv")
  1. Explique que contiene cada una de las columnas de la tabla.
glimpse(bd)
## Rows: 1,028
## Columns: 12
## $ value           <chr> "The Trend  @thetrend___ 19m 19 minutes ago More \"So…
## $ nombre          <chr> "The Trend", "Amir Alonso Pinardel", "Jaime", "Americ…
## $ usuario         <chr> "@thetrend___", "@amiralonsopinar", "@blackjim7", "@A…
## $ fecha           <chr> "2019-10-05", "2019-10-05", "2019-10-05", "2019-10-05…
## $ retweets        <dbl> 3, NA, NA, 1, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, …
## $ like            <dbl> 6, 1, 2, NA, NA, 1, 1, NA, 1, NA, NA, 1, NA, 2, 25, 3…
## $ replies         <dbl> NA, 1, NA, NA, NA, NA, 1, NA, 1, NA, NA, NA, NA, 1, 3…
## $ texto           <chr> "\"Solía pensar que mi vida era una tragedia, pero ah…
## $ hashtags        <chr> "#Joker, #Guasón, #JokerMovie", "#Joker", "#JokerMovi…
## $ ctasMencionadas <chr> NA, "@jokermovie, @comicsarg", NA, "@AHSFX, @jokermov…
## $ nombres_propios <chr> "Solía, Joaquin, Phoenix, Joker, Guasón, JokerMovie",…
## $ fecha2          <date> 2019-10-05, 2019-10-05, 2019-10-05, 2019-10-05, 2019…

La tabla contiene 1,028 elementos con 12 columnas. Estas representan lo dicho en Twitter de la película Joker, desde el posteo en bruto y quién lo hizo (value), nombre de quien lo publicó (name), el usuario que tuiteó (usuario), la fecha, los retweets, me gusta, replies, texto ya filtrado (texto), hashtags, cuentas mencionadas, nombres propios y fecha enformato homologado (fecha2).

  1. Filtre todos los tweets que contiene la frase el bromas. Guárdelos en un objeto llamado bromas e imprima en su documento solamente los primeros 15 renglones (Pista: use la función head().
#Primero sugiero que convirtamos en minúsculas todas las palabras en la columna "texto", por si hubiera una que esté en mayúsculas. Podemos crear otra columna, acá la llamaré "texto2"

bd$texto2 <- str_to_lower(bd$texto)

#Ahora hay que crear el objeto "Bromas", detectando sólo los tuits que tengan el patrón "el bromas"

Bromas <- bd %>% 
  select(texto2) %>% 
  mutate(bromas_tweets = str_detect(string = texto2, pattern = "el bromas")) %>% 
  filter(bromas_tweets == TRUE) 

#Por último, imprimimos los primeros 15 renglones con la función head

head(Bromas, 15)
## # A tibble: 15 x 2
##    texto2                                                          bromas_tweets
##    <chr>                                                           <lgl>        
##  1 "el nuevo guasón aka “el bromas” o “the joker” me recordó un b… TRUE         
##  2 ".   🎬  🎥  🖤  🐾  🎼  📷  🎶joker / guason / el bromas @jokermovie… TRUE         
##  3 "cuando te quieres burlar de los españoles inventando que a la… TRUE         
##  4 "🇬🇹el bromas  #jokermovie #jokerfilm #joker #guason"            TRUE         
##  5 "el guasón   the joker  el bromas  lenín moreno  #jokermovie"   TRUE         
##  6 ". zafra a.   🦇: the joker : el bromas : el guasón : el guaco … TRUE         
##  7 "🃏ahora resulta que todos son fans del bromas!  #jokermovie #j… TRUE         
##  8 "el nombre en español debería ser \"el arlequin\", no el broma… TRUE         
##  9 "¿es neta que en españa al \"joker\" alias el \"guasón\" le ll… TRUE         
## 10 "\uf8ff the joker  el guasón  ¿el bromas? ¡no se pasen!    #jo… TRUE         
## 11 "a bailar al ritmo del peter y de 'el bromas'  #spiderman #spi… TRUE         
## 12 "el bromas estuvo bien cabrona. será que tenemos un segundo gu… TRUE         
## 13 "esta con madre el promocional del \"el bromas\" #dc #guasón #… TRUE         
## 14 "noticia de ultimo momento  acaban de detener a \"el bromas\" … TRUE         
## 15 "#joaquinphoenix #jokermovie  guasón el bromas"                 TRUE
  1. Genere un objeto llamado bd_censurada en el cual elimine todos los tweets que tienen groserías. Usted defina qué palabras entiende por groserías.

Tuve problemas para este ejercicio, así que recurrí a internet. Encontré esta solución temporal

# Creamos un patrón de las groserías que queremos eliminar
pat_gros <- c("puta", "hija de puta", "puto", "hijueputa", "cabronada", "estupido", "idiota", "mierda", "pinche", "chingªd@")

#Con la siguiete fórmula creamos el objeto bd_censurada, que eliminará todas los tuits que contienen malas palabras (los que ya habíamos seleccionado)

bd_censurada <- bd[ !grepl(paste(pat_gros, collapse="|"), bd$texto2),]
  1. En el mismo objeto, bd_censurada, elimine también todos los tweets que hablan de Guaidó.
#Creamos ahora un patrón con las variables de Guaidó
Guaid <- c("-guaido","guaido","Guaidó", "Guaido")


# La siguente fórmula elimina los tuits que contienen estas variantes

bd_censurada <- bd_censurada[ !grepl(paste(Guaid, collapse="|"), bd_censurada$texto2),]


head(bd_censurada$texto2) 
## [1] "\"solía pensar que mi vida era una tragedia, pero ahora me doy cuenta que es una comedia\"... joaquin phoenix, el actor que el mundo aclama en la gran película #joker  #guasón #jokermovie"                                                                      
## [2] "acabo de ver @jokermovie y debo decir que es una verdadera obra cinematográfica. sin duda este guason moviliza y nos pasea por diferentes estados. un #joker psicodélico y símbolo de un sistema injusto, corrompido. un auténtico agente del caos!!! @comicsarg" 
## [3] "estoy sin palabras! joaquin maestro!  #jokermovie #joker #guason #elbromas   11/10"                                                                                                                                                                               
## [4] "la magistral frances conroy participa en la película del icónico personaje de dc comics joker (guasón) interpretando a la mamá del protagonista penny fleck.  no se pierdan su excelente participación a la que nos tiene acostumbrados   #ahs @ahsfx @jokermovie"
## [5] "“the worst part of having a mental illness is people expect you to behave as if you don't.” joker (2019)  #jokermovie   \"la peor parte de tener una enfermedad mental es que la gente espera que te comportes como si no la tuvieras\" guasón (2019)"            
## [6] "#joker bate records en su primer día de proyecciones  #jokermovie #jokerfilm #guason https://redlan.com.ar/index.php/2019/10/05/joker-bate-records-en-su-primer-dia-de-proyecciones/ …"
  1. Reemplace la palabra “Guasón” por la palabra “Joker” en todos los tweets.

Hay que crear un diccionario de reemplazo de las palabras guasón y guason, para que sean joker.

remp <- c("guason" = "joker",
          "guasón" = "joker")

Después hacemos el reemplazo, en este caso crearé una columna llamada “español” para hacer el comparativo con “texto2” (que era nuestro texto en minúsculas)

reemplazo <- bd %>% 
  select(texto2) %>% 
  mutate(español = str_replace_all(texto2, remp)) 

#Imprimir los primeros 15 resultados

head(reemplazo, 15)
## # A tibble: 15 x 2
##    texto2                                 español                               
##    <chr>                                  <chr>                                 
##  1 "\"solía pensar que mi vida era una t… "\"solía pensar que mi vida era una t…
##  2 "acabo de ver @jokermovie y debo deci… "acabo de ver @jokermovie y debo deci…
##  3 "estoy sin palabras! joaquin maestro!… "estoy sin palabras! joaquin maestro!…
##  4 "la magistral frances conroy particip… "la magistral frances conroy particip…
##  5 "“the worst part of having a mental i… "“the worst part of having a mental i…
##  6 "#joker bate records en su primer día… "#joker bate records en su primer día…
##  7 "\uf8ffviðarr odinson \uf8ff retweete… "\uf8ffviðarr odinson \uf8ff retweete…
##  8 "replying to @oswaldoriosm @jokermovi… "replying to @oswaldoriosm @jokermovi…
##  9 "cuando te enteras que el guasón y el… "cuando te enteras que el joker y el …
## 10 "replying to @warkentin @jokermovie s… "replying to @warkentin @jokermovie s…
## 11 "el nuevo guasón aka “el bromas” o “t… "el nuevo joker aka “el bromas” o “th…
## 12 ".   🎬  🎥  🖤  🐾  🎼  📷  🎶joker / guaso… ".   🎬  🎥  🖤  🐾  🎼  📷  🎶joker / joker…
## 13 "guasón / joker ★★★★★ @jokermovie"     "joker / joker ★★★★★ @jokermovie"     
## 14 "haciendo mi tarea para ver @jokermov… "haciendo mi tarea para ver @jokermov…
## 15 "¡intensa, hilarante y perturbadora! … "¡intensa, hilarante y perturbadora! …
  1. ¿Cual fué el Tweet más retuiteado? ¿Cual el que tuvo más likes?

En este caso, hay que extraer numéricamente los likes con arrange (el signo menos para que le de orden), elegí top_n para ver los 10 con más likes, podemos ver que los primeros likes los tiene el mismo tuit, habría que analizar ese dato para ver si no está repetido. El de más likes es el de @pagusrendon, con 517 likes

bd %>% 
  arrange(-like) %>%
  top_n(10, like) %>% 
  select(usuario, like, texto)
## # A tibble: 10 x 3
##    usuario        like texto                                                    
##    <chr>         <dbl> <chr>                                                    
##  1 @pagusrendon    517 EEUU  Joker  Italia  Burlone   México  Guasón  España El…
##  2 @warkentin      499 A mi me gustó @jokermovie.  Mucho.  Mucho mucho.         
##  3 @DCcomicsMX     455 El Verdadero Origen del #Joker   ¿Conoces The Man Who La…
##  4 @DCcomicsMX     453 El Verdadero Origen del #Joker   ¿Conoces The Man Who La…
##  5 @DCcomicsMX     453 El Verdadero Origen del #Joker   ¿Conoces The Man Who La…
##  6 @gioalicari     408 💎#Guason #JokerMovie imposible no pensar en heath ledger…
##  7 @SanCadilla     304 Ya fui a ver El Guasón y parece una película de héroes, …
##  8 @connieansal…   275 Totalmente en Shock con el Guason. Imposible no querer a…
##  9 @DCcomicsMX     243 SIN SPOILERS ¡YA VIMOS #JOKER Y QUEDAMOS IMPACTADOS!  No…
## 10 @DCcomicsMX     176 Ya sea en cómic, animación o Live Action, todas las enca…

En el caso de los retuits, utilizaremos la misma fórmula sólo con la columna ‘retweets’. Veremos que de más retuits fue el de la cuenta @DCComicsMX, con 148, que también ocupa el segundo y tercer lugar con el mismo tuit.

bd %>% 
  arrange(-retweets) %>%
  top_n(10, retweets) %>% 
  select(usuario, retweets, texto)
## # A tibble: 11 x 3
##    usuario     retweets texto                                                   
##    <chr>          <dbl> <chr>                                                   
##  1 @DCcomicsMX      148 El Verdadero Origen del #Joker   ¿Conoces The Man Who L…
##  2 @DCcomicsMX      148 El Verdadero Origen del #Joker   ¿Conoces The Man Who L…
##  3 @DCcomicsMX      147 El Verdadero Origen del #Joker   ¿Conoces The Man Who L…
##  4 @gioalicari       74 💎#Guason #JokerMovie imposible no pensar en heath ledge…
##  5 @pagusrend…       65 EEUU  Joker  Italia  Burlone   México  Guasón  España E…
##  6 @DCcomicsMX       46 Ya sea en cómic, animación o Live Action, todas las enc…
##  7 @DCcomicsMX       45 Ya sea en cómic, animación o Live Action, todas las enc…
##  8 @DCcomicsMX       45 Ya sea en cómic, animación o Live Action, todas las enc…
##  9 @SanCadilla       44 Ya fui a ver El Guasón y parece una película de héroes,…
## 10 @El_Abogad        40 🐼  ⚖¿Qué obtienes cuándo mezclas a un enfermo mental y …
## 11 @Undiasoy         40 ♡Lo peor de tener una enfermedad mental es que la gente…
  1. ¿Quienes fueron los usuarios que tuitearon más veces durante el periodo de obtención de la información?

Para este resultado haremos uso de la función count y sort para que lo ordene. Podemos ver que el usuario que más tuiteó fue @DCComicsMX, 14 veces.

bd %>% 
  count(usuario, sort = TRUE) %>%
  top_n(10) 
## # A tibble: 10 x 2
##    usuario              n
##    <chr>            <int>
##  1 @DCcomicsMX         14
##  2 @FormerlyKnow       10
##  3 @guillemancandy      8
##  4 @elespectador        6
##  5 @VerGuason_2019      6
##  6 @altapeli            5
##  7 @JMRivaPalacio       5
##  8 @danitafashion       4
##  9 @edwin_digital       4
## 10 @InconformeSiem1     4
  1. Genere una gráfica de barras donde el eje “y” sea el nombre de usuario y la altura de las barras sea el número de tweets escritos.

Se puede crear una gráfica desde un nuevo tibble para no alentar el equipo, pero si no, sólo hay que crear un nuevo objetoy graficarlo.

#Creamos el objeto Usuarios

Usuarios <- bd %>% 
  count(usuario, sort = TRUE) %>%
  top_n(5) 
#Hacemos la gráfica

library(ggplot2)

Usuarios %>%
  ggplot(aes(x=n, y=usuario)) + 
  geom_bar(colour="black", fill="#DD8888", width=.8, stat="identity") + 
  geom_text(aes(label=n), hjust=2,color="black", size=4) +
  guides(fill=FALSE) +
  xlab("Número de tuits") + ylab("Usuario") +
  ggtitle("¿Quién tuiteó más sobre la película Joker")


Ejercicio 05.

Proyecto final. Avance. (Sólo alumnos inscritos).

Me gusta mucho la idea de manejar bases de datos con lo que publican los usuarios en Twitter. El proyecto podría ser un análisis de lo publicado en determinado momento en redes sociales. También puede ser analizar discursos, sé que es retador pero sería muy bueno para mi carrera.