En este código, estaremos webscrapping que es la extracción de información de sitios web y estaremos realizando la limpieza de texto a un código creado para poder conocer la frecuencia de las palabras más repetidad en las mañaneras del presidente Andrés Manuel lópez Obrador. Esto en un lapso de tiempo del 1 de junio al 24 de agosto y se hace con el fin de poder realizar futuras operaciones como analizar tendencias, concoer sus temas de interés o hacer análisis de sentimientos.
Primero empezamos a utilizar las librerías de rvest y magrittr que nos sirven para extraer cierto contenido de una página web y que las utilizaremos más adelante. En este caso, extraeremos la información de las mañaneras de la página oficial de gobierno. Después, mediante la variabel “URL” extraeremos el URL de la página web que utilizaremos, en este caso, primero haremos el de la mañanera del 9 de agosto del 2023, de la página oficial del gobierno. Posteriormente, se usa la función read_html(url) para poder acceder y leer el contenido HTML del URL y lo almacenamos en la variable “pagina”.
Después, en este punto establecemos la fecha de la conferencia del 9 de agosto del 2023 y la guardamos en la variable “fecha_conferencia”. Creamos un archivo para guardar el contenido que extraímos en un archivo txt. Por último, utilizamos la función “writeLines” para guardar el contenido que extraímos en el archivo con el nombre creado anteriormente.
NOTA IMPORTANTE: Utilizamos el operador de %>% para encadenar y darle continuidad al código.
library(rvest) library(magrittr)
pagina <- read_html(url)
texto <- pagina %>% #html_nodes(“XPATH_o_CSS_selector”) %>% html_text()
fecha_conferencia <- “9_de_agosto_de_2023” # Esta es una forma simple, pero puedes obtener la fecha de la URL o de otra parte si es dinámica. nombre_archivo <- paste0(“conferencia_”, fecha_conferencia, “.txt”)
writeLines(texto, nombre_archivo)
Como se mencionó anteriormente utilizaremos un rango de tiempo, por lo que primero definimos un rango de fechas desde el 1 de junio de 2023 hasta el 24 de agosto de 2023 (en este caso) usando la función seq.Date y la parte de “by=”days”” te permite descargar y hacer operaciones por día.
Cargamos las librerías rvest y magrittr que definimos también en el chunk anterior y definimos una función llamada scrape_y_guarda que realizará el web scraping y guardará los contenidos en archivos de texto. Es necesario que nuestros archivos de texto estén en español, por lo que cambiaremos el idioma a español utilizando el comando Sys.setlocale(“LC_TIME”, “es_ES.UTF-8”). Esto es importante para que el formato de fecha en español funcione correctamente y podamos correr todo el código siguiente. Después formateamos la fecha actual en día, mes y año para construir la URL de la página de conferencia correspondiente y poder identificarla de mejor manera. Con lo anterior, creamos la URL utilizando la fecha formateada en la variable fecha_url. Seguimos guardando el link que usaremos y del cuál extraeremos todas las mañaneras en una variable llamada “url”, seguido de nuestra variable de “fecha_url” para extraer cada mañanera diaria. Usamos de nuevo el comando read_html para obtener el contenido HTML de la página de conferencia, el cuál nos servirá para crear el nombre del archivo utilizando la fecha formateada, donde además cambiamos los guiones a guiones bajos en el nombre de cada archivo.
Por último, utilizamos de nuevo la función writeLines para guardar el contenido que extraimos en el archivo con el nombre creado anteriormente y la funicón lapply se usa para poder aplicar el comando scrape_y_guarda a cada fecha en el rango definido.La función lapply nos sirve para cuando quieres aplicar la misma función a múltiples elementos en una lista o base de datos.
fechas <- seq.Date(as.Date(“2023-06-01”), as.Date(“2023-08-24”), by=“days”)
library(rvest) library(magrittr)
scrape_y_guarda <- function(fecha) { # Cambia el local a español Sys.setlocale(“LC_TIME”, “es_ES.UTF-8”) # Formatea la fecha para la URL # Formatea la fecha para la URL dia <- as.numeric(format(fecha, “%d”)) mes <- format(fecha, “%B”) #MES_NUM <- FORMAT(FECHA, “%M”) ano <- format(fecha, “%Y”) fecha_url <- paste(dia, “de”, mes, “de”, ano, sep=“-”) url <- paste0(“https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-del-presidente-andres-manuel-lopez-obrador-del-”, fecha_url)
# Intenta hacer el webscraping pagina <- read_html(url)
# Suponiendo que el contenido de la conferencia está en un selector específico, como# (es necesario verificar y ajustar este selector de acuerdo al código fuente real de la página) texto <- pagina %>% #html_nodes(“.contenido-conferencia”) %>% # <– reemplaza “.contenido-conferencia” con el selector CSS correcto html_text()
# Crea el nombre del archivo y lo guarda nombre_archivo <- paste0(“conferencia_”, gsub(“-de-”, “_“, fecha_url),”.txt”) writeLines(texto, nombre_archivo) }
lapply(fechas, scrape_y_guarda)
pasteO(“conferencia_”, ano, “”, mes_num, ””, dia, “.txt”)
En esta parte, eliminaremos todos aquellos archivos que contengan la leyenda “Sitio en mantenimiento”. Empezaremos utilizando la función list.files() que nos ayuda a obtener una lista de nombres de archivos de nuestro directorio y al escribir “.txt” delimitamos que sólo sean archivos de ese tipo y los almacenamos en la variable archivos. Después hemos definido una variable llamada verificar_y_eliminar que toma los archivos. Tenemos readLines(archivo, warn = FALSE): Esta función lee el archivo línea por línea y devuelve un vector donde cada elemento es una línea del archivo.
Después tenemos el argumento texto <- paste(texto, collapse = ” “): Concatena todas las líneas del archivo en un solo string, separándolas por espacios. Esto es útil para buscar la cadena de texto completa.
Seguimos con la condición de que si el archivo contiene la leyenda de “Sitio en mantenimiento, sea eliminado”. Con el comando grepl podemos buscar esa leyenda en específico dentro de los archivos.Si existe la leyenda, “grepl” se vuele TRUE y si no, se vuelve FALSE.Después de confirmarse que es TRUE y de que existe la leyenda, sigue la función que remueve el archivo: file.remove(archivo) y con cat(paste(“Archivo eliminado:”, archivo, “”)) se imprime el mensaje de que cierto archivo ha sido eliminado.Por último, se utiliza la función lapply() para aplicar la función verificar_y_eliminar. Si un archivo contiene la cadena “Sitio en mantenimiento”, será eliminado, y se imprimirá un mensaje para informar sobre los archivos eliminados.
#Eliminar archivos son leyenda "Sitio en mantenimiento"
#Este código busca archivos .txt en el directorio de trabajo actual, verifica si contienen la leyenda "Sitio en mantenimiento" y, en caso afirmativo, elimina esos archivos y notifica al usuario sobre los archivos eliminados.
# Lista de archivos .txt en el directorio actual
#list.files(): Esta función devuelve una lista de nombres de archivos en el directorio de trabajo actual.
#pattern = "*.txt": Esta es una expresión regular que indica que sólo quieres listar archivos que terminen en .txt, es decir, archivos de texto.
archivos <- list.files(pattern = "*.txt")
# Función para verificar y eliminar archivos no deseados
verificar_y_eliminar <- function(archivo) {
#readLines(archivo, warn = FALSE): Esta función lee el archivo línea por línea y devuelve un vector donde cada elemento es una línea del archivo.
#warn = FALSE: Evita que se muestren advertencias en caso de problemas al leer el archivo.
texto <- readLines(archivo, warn = FALSE)
#paste(): Esta función concatena el vector de líneas (anteriormente leído) en un solo string.
#collapse = " ": Indica que las líneas se deben separar con un espacio.
texto <- paste(texto, collapse = " ")
# Si el archivo contiene "Sitio en mantenimiento", eliminarlo
#grepl(): Esta función busca una expresión regular (en este caso, la cadena "Sitio en mantenimiento") dentro del texto. Si la encuentra, devuelve TRUE; de lo contrario, devuelve FALSE.
#ignore.case = TRUE: Ignora la diferencia entre mayúsculas y minúsculas al buscar la cadena.
#****después de leerlo los va a concatenar texto y eliminar los que digan "" fnc cat -> dice cuales eliminaste
if (grepl("Sitio en mantenimiento", texto, ignore.case = TRUE)) {
file.remove(archivo)
cat(paste("Archivo eliminado:", archivo, "\n"))
}
}
#Si el condicional anterior es verdadero (es decir, si el archivo contiene "Sitio en mantenimiento"), esta línea elimina el archivo.
# Aplicar la función a cada archivo
lapply(archivos, verificar_y_eliminar)
## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## NULL
##
## [[4]]
## NULL
##
## [[5]]
## NULL
##
## [[6]]
## NULL
##
## [[7]]
## NULL
##
## [[8]]
## NULL
##
## [[9]]
## NULL
##
## [[10]]
## NULL
##
## [[11]]
## NULL
##
## [[12]]
## NULL
##
## [[13]]
## NULL
##
## [[14]]
## NULL
##
## [[15]]
## NULL
##
## [[16]]
## NULL
##
## [[17]]
## NULL
##
## [[18]]
## NULL
##
## [[19]]
## NULL
##
## [[20]]
## NULL
##
## [[21]]
## NULL
##
## [[22]]
## NULL
##
## [[23]]
## NULL
##
## [[24]]
## NULL
##
## [[25]]
## NULL
##
## [[26]]
## NULL
##
## [[27]]
## NULL
##
## [[28]]
## NULL
##
## [[29]]
## NULL
##
## [[30]]
## NULL
##
## [[31]]
## NULL
##
## [[32]]
## NULL
##
## [[33]]
## NULL
##
## [[34]]
## NULL
##
## [[35]]
## NULL
##
## [[36]]
## NULL
##
## [[37]]
## NULL
##
## [[38]]
## NULL
##
## [[39]]
## NULL
##
## [[40]]
## NULL
##
## [[41]]
## NULL
##
## [[42]]
## NULL
##
## [[43]]
## NULL
##
## [[44]]
## NULL
##
## [[45]]
## NULL
En esta sección seguiremos realizando una limpieza.Primero utilizaremos la función list.files() que nos listará aquellos archivos que tengan el formato .txt y los guardaremos en la variable “archivo”. Después, empezamos la limpieza del texto donde con la función limpiar_texto que toma un archivo y empieza los siguientes procesos de limpieza:
readLines(archivo, warn = FALSE):cómo dice el mismo comando, este lee el contenido del archivo línea por línea y lo almacena en la variable “texto”. En esta misma instrucción incluimos warn = FALSE que no permite que se muestren advertencias en caso de que exista algún problema para leer el archivo.
Después tenemos texto <- paste(texto, collapse = ” “): Función que ya habíamos usado anteriormente donde concatena todas las líneas previamente leídas en un sólo string y las separa por espacios.
Siguiendo con texto <- tolower(texto): este comando es muy importante porque en esta parte estamos convirtiendo todas las palabras de mayúsculas a minúsculas para que todo el texto se vuelva uniforme y su análisis sea más fácil.
texto <- gsub(“http\S+|www\.\S+”, ““, texto): Usamos este comando para encontrar las URLs que empiecen en http o www.
Siguiendo con la limpieza, texto <- gsub(“<.*?>“,”“, texto): elimina las etiquetas html.También, usamos texto <- gsub(”[[:punct:]]“,”“, texto) que nos ayuda a liminar cualquier signo de puntuación (signos, puntos, etc). También eliminamos números con texto <- gsub(”\d+“,”“, texto) y remplazamos cualquier secuencia de espacios, con espacios únicos con la función texto <- gsub(”\s+“,” “, texto). Después de esto, el texto queda limpio.
Ya sólo queda aplicar esta función de limpieza para todos los archivos y para esto utilizamos la antes mencionada función “lapply”. Esto significa que esta función se aplicará a cada archivo de mañanera y los textos limpios serán almacenados en la variable textos_limpios.
# Lista de archivos .txt en el directorio actual
archivos <- list.files(pattern = "*.txt")
#list.files(pattern = "*.txt"): Lista todos los archivos en el directorio de trabajo actual que tengan la extensión .txt. Estos nombres de archivos se guardan en el vector archivos.
# Función para limpiar el texto
# ***** Leer y juntar todos los archivos para trabajar
limpiar_texto <- function(archivo) {
texto <- readLines(archivo, warn = FALSE)
texto <- paste(texto, collapse = " ")
# tolower(texto): Convierte todo el texto a minúsculas para que el análisis y limpieza sean uniformes.
texto <- tolower(texto)
# Eliminar URLs: gsub("http\S+|www\.\S+", "", texto): Usa una expresión regular para encontrar URLs que comiencen con "http" o "www" y las reemplaza con una cadena vacía, esencialmente eliminándolas.
texto <- gsub("http\\S+|www\\.\\S+", "", texto)
# Eliminar etiquetas HTML (si las hubiera): gsub("<.*?>", "", texto): Si hubiera alguna etiqueta HTML en el texto, esta expresión regular las identificaría y las eliminaría.
texto <- gsub("<.*?>", "", texto)
# Eliminar puntuación: gsub("[[:punct:]]", "", texto): Elimina cualquier carácter de puntuación del texto.
texto <- gsub("[[:punct:]]", "", texto)
# Eliminar números: gsub("\d+", "", texto): Elimina cualquier secuencia de números.
texto <- gsub("\\d+", "", texto)
# Eliminar espacios extra: gsub("\s+", " ", texto): Reemplaza cualquier secuencia de espacios (uno o más) con un único espacio.
texto <- gsub("\\s+", " ", texto)
return(texto)
}
# Aplicar la función de limpieza a cada archivo
textos_limpios <- lapply(archivos, limpiar_texto)
Este código utiliza la biblioteca tm para crear una matriz Document-Term Matrix (DTM) a partir de un corpus de textos limpios. Primero cargamos esa librería mencionada para posteriormente crear un corpus de los textos limpios. Un corpus es una colección de archivos de texto. La parte del comando VectorSource(textos_limpios) nos permite convertir los textos limpios en un objeto que se puede utilizar como fuente de datos para el corpus.
Después creamos una Document-Term Matrix (DTM) para crear la matriz a partir del corpus. Una DTM es una matriz en la que las filas representan archivos y las columnas representan las palabras. Cada celda es un recuento de cuántas veces aparece cierto término en específico.
Por último, sólo inspeccionamos la matriz creada con la función inspect() para ver su contenido.Los documentos ahora tendrán forma de matriz.La DTM se utiliza para realizar análisis de un texto.
library(tm)
## Warning: package 'tm' was built under R version 4.2.3
## Loading required package: NLP
#Crear corpus con textos limpios
corpus <- Corpus(VectorSource(textos_limpios))
#corpus: colección de documentos limpios los vectoriza y a partir de ese se hace matriz
#Documetn Term Matrix
dtm <- DocumentTermMatrix(corpus)
#Ver la Matriz
inspect(dtm)
## <<DocumentTermMatrix (documents: 45, terms: 27280)>>
## Non-/sparse entries: 137993/1089607
## Sparsity : 89%
## Maximal term length: 205
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs con del las los para pero por presidente que una
## 1 122 145 118 255 121 121 161 169 642 131
## 18 156 176 92 273 164 74 169 92 570 152
## 25 166 162 103 297 131 65 136 128 571 94
## 27 155 141 90 296 142 110 129 66 623 97
## 37 182 196 145 244 171 67 160 119 656 145
## 38 241 258 129 217 176 68 165 94 623 125
## 42 148 164 97 243 141 104 129 139 713 97
## 43 148 133 103 356 140 109 164 111 721 136
## 44 148 133 103 356 140 109 164 111 721 136
## 6 173 156 105 246 142 89 163 130 588 87
En esta parte representaremos graficamente lo antes creado para ver la frecuencia de las palabras.Calculamos la frecuencia de las palabras del primer documento en el DTM y se convierte en una matriz de una fila e infinidad de columnas, representando cada una un término y su conteo. La función conteo_primer_doc <- as.matrix(dtm[1,]) nos permite realizar proceso anterior. Realiza un ordenamiento decreciente para mostrar las palabras más frecuentes con la función sort(conteo_primer_doc, decreasing = TRUE) y se calcula el conteo total de cada término en todos los documentos con la función colSums(as.matrix(dtm)) y sumamos las columnas de la DTM. Esta operación se guarda en la variable conteo_total. Después muestra los 50 términos más comunes de todos los archivos (head(terminos_comunes, 50)).
Posteriormente, instalamos la librería “wordcloud” que se utiliza para crear nubes de palabras para proceder a crearla con los términos más comunes wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 1, max.words = 100, random.order = FALSE, rot.per = 0.35, colors = brewer.pal(8, “Dark2”)). A continuación explicaré el código anterior parte por parte:
(min.freq = 1): se muestran los términos comunes que aparecen al menos una vez. max.words = 100: se muestran un máximo de 100 palabras. random.order = FALSE: al escribir “FALSE” permite que las palabras tengan un orden y acomodo mejor para poder tener un mejor entendimiento. Lo siguiente es cuestión de formato y colores: estos se pueden ajustar dependiendo de las necesidades. Los colores de la nube de palabras se seleccionan de una paleta de colores llamada “Dark2”.
Esta nube de palabras te mostrará visualmente cuáles son los términos más frecuentes en los archivos de las mañaneras.
# Conteo de palabras del primer documento y convierte en matriz de 1 fila(documento) de infinitas columnas (terminos)
conteo_primer_doc <- as.matrix(dtm[1,])
# Acomodo decreciente
#sort(conteo_primer_doc, decreasing = TRUE)
# Sumar las columnas para obtener el conteo total de cada término. Matriz solamente de términos, y con colSums hace un total de cada columna. Suma de cada una de las veces que se dice un término
conteo_total <- colSums(as.matrix(dtm))
# Ordenar y mostrar los términos más comúnes
terminos_comunes <- sort(conteo_total, decreasing = TRUE)
head(terminos_comunes, 50) # Mostrar los 50 términos más comunes
## que los del con por para presidente
## 23031 9398 6448 5677 5491 4976 4398
## una las pero porque más como lópez
## 4270 4156 3343 3216 3052 2710 2675
## manuel andrés también hay eso está muy
## 2629 2590 2484 2424 2282 2222 2141
## este var sí obrador entonces todo mil
## 2059 2025 1982 1894 1825 1742 1703
## qué vamos son méxico nos esto todos
## 1669 1629 1614 1575 1540 1522 1457
## gobierno tiene pues esta están aquí fue
## 1415 1392 1340 1306 1294 1266 1236
## estamos les dimension bueno ver ahí estado
## 1173 1141 1125 1121 1113 1075 1061
## ahora
## 1038
# Instalar y cargar el paquete wordcloud
#install.packages("wordcloud")
library(wordcloud)
## Warning: package 'wordcloud' was built under R version 4.2.3
## Loading required package: RColorBrewer
# Crear la nube de palabras
# se van a plotear los términos comunes (base) que aparecen más de una vez y máximo 100.
wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 1, max.words = 100, random.order = FALSE)
Como podemos ver nuestra nube tiene muchas palabras que son muy comunes y generan ruido en nuestro análisis que no agregan valor al análisis. Eliminar stoprwords, que son pronombres, artículos, preposiciones, es un paso comín en el procesamiento de datos de texto. Antes de generar dtm es pertinente eliminar este tipo de palabras
Las stopwrods o palabras vacías (como su traducción en español). Son todas aquellas palabras que no tienen significado de manera individual, es por eso que en los procesamientos de busqueda, esta palabras no son tomadas en cuenta. Ahora lo que haremos es eliminar todas esas palabras para que nos ayuden a limpiar el rango de palabras
# eliminar stopwords de nuestro corpus
corpus_limpio <- tm_map(corpus, removeWords, stopwords("es")) #Usar "es" (español) para stopwords en español
## Warning in tm_map.SimpleCorpus(corpus, removeWords, stopwords("es")):
## transformation drops documents
##Repetimos el análisis y comparamos los términos y la nube
# Creamos nuevo dtm
dtm_limpio <- DocumentTermMatrix(corpus_limpio)
#Ver matriz
inspect(dtm_limpio)
## <<DocumentTermMatrix (documents: 45, terms: 26459)>>
## Non-/sparse entries: 131467/1059188
## Sparsity : 89%
## Maximal term length: 205
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs andrés entonces lópez manuel méxico mil obrador presidente vamos var
## 1 111 47 114 110 35 43 110 169 23 45
## 16 35 25 36 39 94 64 35 91 46 45
## 18 42 43 43 44 44 45 9 92 49 45
## 25 70 32 72 70 33 91 70 128 34 45
## 37 74 30 77 77 24 55 11 119 33 45
## 38 55 46 55 59 41 40 14 94 45 45
## 42 86 101 90 96 30 31 10 139 39 45
## 43 83 64 87 83 55 33 85 111 50 45
## 44 83 64 87 83 55 33 85 111 50 45
## 6 66 42 66 61 28 25 9 130 47 45
# Sumar las columnas para obtener el conteo total de cada término
conteo_total_limpio <- colSums(as.matrix(dtm_limpio))
# Ordenar y mostrar los términos más comúnes
terminos_comunes_limpio <- sort(conteo_total_limpio, decreasing = TRUE)
head(terminos_comunes_limpio, 50)
## presidente lópez manuel andrés var
## 4398 2675 2629 2590 2025
## obrador entonces mil vamos méxico
## 1894 1825 1703 1629 1575
## gobierno pues aquí dimension bueno
## 1415 1340 1266 1125 1121
## ver ahí ahora dos cómo
## 1113 1075 1038 916 898
## millones gente así pueblo caso
## 890 868 846 827 813
## function pesos ciento null señor
## 765 746 726 720 720
## van usted ser hacer pagetype
## 717 702 698 690 675
## país bien año días años
## 667 666 644 639 632
## gagobtrackerset voy información tren tres
## 630 603 597 584 578
## hace nacional poder decir puede
## 577 572 548 538 528
Como se puede observar, las palabras vacían ya no aparecen en la tabla de conteo_total_limpio. Sin embargo para un análisis más preciso de las mañaneras se tiene que eliminar ciertas palabras que son una contante en cada mañanera.
Para esta limpieza no solo se necesitan eliminar las palabras nulas, también las palabras que no aportan ningun valor a la conversación/conferencia; en ejemplo de ellos son presidente, Andres Manuel o aquellas que suelen estar asociados a la descripción de un objeto o cifra cien mil, etc.
NOTA: Antes de hacer esta limpieza, se necesitan mostrar que palabras son las que más se repiten para poder hacer la limpieza de manera efectiva, una manera de hacerlo es través de un gráfica o de algun medio visual, en este caso una nube de palabras
# Crear nueva nube de palabras
wordcloud(names(terminos_comunes_limpio),
terminos_comunes_limpio,
min.freq = 1,
max.words = 200,
random.order = FALSE,
rot.per = 0.35,
colors = brewer.pal(8, "Dark2"))
Como se puede observar, las palabras que más se repiten están de un tamaño más grande y de un color distitnto que corresponde a la frecuencia en comparación a otras palabras. Sin embargo, existen complicaciones para este tipo de gráfica, ya que sin una tabla de frecuencias, el gráfico visual no mostrará de manera exacta todas las palabras que se encuentre en su frecuencia máxima debido a la extención de la misma. Algunas de las que no se muestran debido a su extención son:
Estas palabras resultan importantes para un analisis posterior, por lo que no pueden quedar fuera de el gráfico , para ello será necesario crear la tabla de frecuencia e identificar las palabras a eliminar
# Obtener la tabla de frecuencias de los términos
tabla_frecuencias <- table(conteo_total_limpio)
# Mostrar los términos más comunes junto con sus frecuencias
resultados <- data.frame(Termino = names(terminos_comunes_limpio),
Frecuencia = terminos_comunes_limpio,
Total = tabla_frecuencias[names(terminos_comunes_limpio)])
# Se despliega las primeras 50 palabras con mayor frecuencia
head(resultados, 100)
## Termino Frecuencia Total.conteo_total_limpio Total.Freq
## presidente presidente 4398 <NA> NA
## lópez lópez 2675 <NA> NA
## manuel manuel 2629 <NA> NA
## andrés andrés 2590 <NA> NA
## var var 2025 <NA> NA
## obrador obrador 1894 <NA> NA
## entonces entonces 1825 <NA> NA
## mil mil 1703 <NA> NA
## vamos vamos 1629 <NA> NA
## méxico méxico 1575 <NA> NA
## gobierno gobierno 1415 <NA> NA
## pues pues 1340 <NA> NA
## aquí aquí 1266 <NA> NA
## dimension dimension 1125 <NA> NA
## bueno bueno 1121 <NA> NA
## ver ver 1113 <NA> NA
## ahí ahí 1075 <NA> NA
## ahora ahora 1038 <NA> NA
## dos dos 916 <NA> NA
## cómo cómo 898 <NA> NA
## millones millones 890 <NA> NA
## gente gente 868 <NA> NA
## así así 846 <NA> NA
## pueblo pueblo 827 <NA> NA
## caso caso 813 <NA> NA
## function function 765 <NA> NA
## pesos pesos 746 <NA> NA
## ciento ciento 726 <NA> NA
## null null 720 <NA> NA
## señor señor 720 <NA> NA
## van van 717 <NA> NA
## usted usted 702 <NA> NA
## ser ser 698 <NA> NA
## hacer hacer 690 <NA> NA
## pagetype pagetype 675 <NA> NA
## país país 667 <NA> NA
## bien bien 666 <NA> NA
## año año 644 <NA> NA
## días días 639 <NA> NA
## años años 632 <NA> NA
## gagobtrackerset gagobtrackerset 630 <NA> NA
## voy voy 603 <NA> NA
## información información 597 <NA> NA
## tren tren 584 <NA> NA
## tres tres 578 <NA> NA
## hace hace 577 <NA> NA
## nacional nacional 572 <NA> NA
## poder poder 548 <NA> NA
## decir decir 538 <NA> NA
## puede puede 528 <NA> NA
## mismo mismo 517 <NA> NA
## prensa prensa 513 <NA> NA
## parte parte 512 <NA> NA
## gracias gracias 505 <NA> NA
## hoy hoy 500 <NA> NA
## seguridad seguridad 496 <NA> NA
## gtagset gtagset 495 <NA> NA
## pregunta pregunta 495 <NA> NA
## luego luego 488 <NA> NA
## manera manera 488 <NA> NA
## conferencia conferencia 484 <NA> NA
## importante importante 484 <NA> NA
## tiempo tiempo 481 <NA> NA
## todas todas 475 <NA> NA
## tema tema 474 <NA> NA
## además además 473 <NA> NA
## presidencia presidencia 465 <NA> NA
## sólo sólo 463 <NA> NA
## tener tener 463 <NA> NA
## nuevo nuevo 461 <NA> NA
## personas personas 454 <NA> NA
## haciendo haciendo 452 <NA> NA
## obrador obrador 442 <NA> NA
## general general 439 <NA> NA
## salud salud 437 <NA> NA
## medios medios 435 <NA> NA
## versión versión 423 <NA> NA
## buenos buenos 415 <NA> NA
## unidos unidos 412 <NA> NA
## estenográfica estenográfica 406 <NA> NA
## ciudad ciudad 404 <NA> NA
## trabajo trabajo 398 <NA> NA
## interlocutor interlocutor 396 <NA> NA
## toda toda 391 <NA> NA
## siempre siempre 383 <NA> NA
## maya maya 382 <NA> NA
## día día 377 <NA> NA
## agua agua 377 <NA> NA
## creo creo 368 <NA> NA
## mejor mejor 357 <NA> NA
## muchas muchas 355 <NA> NA
## ejemplo ejemplo 351 <NA> NA
## proceso proceso 351 <NA> NA
## zona zona 351 <NA> NA
## social social 346 <NA> NA
## dinero dinero 344 <NA> NA
## menos menos 342 <NA> NA
## siguiente siguiente 342 <NA> NA
## gran gran 339 <NA> NA
## acuerdo acuerdo 338 <NA> NA
Se observa que de las primeras 10 palabras solo méxico resulta relevante para el análisis por lo que el siguiente paso es hacer la limpieza de manera manual
# Crear una matriz de términos y documentos con frecuencias term_document_matrix <- as.matrix(dtm_limpio)
# Convertir la matriz a un data frame para facilitar su manipulación term_document_df <- as.data.frame(term_document_matrix)
# Agregar los nombres de los términos como columna term_document_df$term <- rownames(term_document_matrix)
# Calcular las sumas de frecuencias por término term_document_df$total_frequency <- rowSums(term_document_matrix)
# Ordenar el data frame por frecuencia total de mayor a menor term_document_df <- term_document_df[order(term_document_df$total_frequency), ]
# Imprimir las primeras filas del data frame con las frecuencias de términos head(term_document_df, 50)
Para esta limpieza se considero eliminar algunos verbos
¿Por qué?
Se eliminan los verbos por practicidad y porque, la finalidad de las mañaneras del presidente es :proponer la agenda, el debate y los temas de discusión diarios, al poner los verbos no solo se hace enfasis en las acciones que no sabemos si son ciertas, sino que además quitan espacio a las palabras que son temas y hechos, u ejemplo de ello es chiapas, sin duda un estado que tiene muchas complicaciones politicas, sociales y economicas por el megaproyecto del presidente el tren maya.
# eliminar palabras específicas
palabras_eliminar <- c("null","gtagset","function","var","pagetype", "presidente", "interlocutor",
"andrés", "manuel", "lópez", "obrador", "entonces","pues","ciento","tres","ahí","así","pues","ahora","mil",
"señor", "cómo","dos", "ver","aquí","voy","días","gagobtrackerset","año","van","ser","además","parte", "gracias",
"mismo","conferencia","tiempo","pues","vamos","mil","bueno","aquí","ver","Docs","caso","dimension","millones","usted",
"bien","años","información","hace","buenos","día","creo","mejor","hoy","luego","hacer", "decir","poder","puede",
"manera","todas","importante","pregunta","todas","menos","muchas","quién","dar","cinco","fácil","dice","atención",
"vida","ustedes","vez","empresas","sino","seguir","pagesgroup","ayer","gran","atención","cada","toda","siempre",
"agosto","proceso","haciendo","nuevo","sólo","tener","general", "siguiente","cuatro","gobmx","section","subgroup",
"type","semana","quiero","ejemplo","incluso","empresa","hecho","contentgroup","gaset","organizationname","video",
"cosas","tema","versión","acuerdo","encuesta","grupo","todavía","después","mucha","pueden","cabo","adelante","casos",
"favor","haber","allá","público","veces","data","baja","junio","else","email")
# La función removeWords toma solo dos argumentos: el objeto corpus y las palabras que deseas eliminar.
# Es por eso que al eliminar varias palabras, se tienen que hacer en dos etapas
# Eliminar palabras específicas. ETAPA 1
corpus_3 <- tm_map(corpus, removeWords, palabras_eliminar)
## Warning in tm_map.SimpleCorpus(corpus, removeWords, palabras_eliminar):
## transformation drops documents
# Eliminar stopwords en español
corpus_33 <- tm_map(corpus_3, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(corpus_3, removeWords, stopwords("es")):
## transformation drops documents
# Repetimos el análisis y comparamos los términos y la nube
# Creamos nuevo dtm
dtm_3 <- DocumentTermMatrix(corpus_33)
#Ver matriz
inspect(dtm_3)
## <<DocumentTermMatrix (documents: 45, terms: 26093)>>
## Non-/sparse entries: 125413/1048772
## Sparsity : 89%
## Maximal term length: 205
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs gente gobierno méxico nacional país pesos prensa pueblo seguridad tren
## 1 13 32 35 8 22 24 11 8 8 1
## 16 19 40 94 6 16 14 11 5 11 44
## 18 18 25 44 18 15 41 11 10 5 38
## 25 22 25 33 28 15 25 13 7 24 6
## 37 32 35 24 23 24 40 10 18 14 64
## 38 29 50 41 17 26 39 10 15 5 62
## 42 24 35 30 13 15 7 10 29 15 4
## 43 39 28 55 4 16 7 12 51 1 0
## 44 39 28 55 4 16 7 12 51 1 0
## 6 23 28 28 17 16 36 10 36 6 41
# Sumar las columnas para obtener el conteo total de cada término
conteo_total_3 <- colSums(as.matrix(dtm_3))
# Ordenar y mostrar los términos más comúnes
terminos_comunes_3 <- sort(conteo_total_3, decreasing = TRUE)
head(terminos_comunes_3)
## méxico gobierno gente pueblo pesos país
## 1575 1415 868 827 746 667
# Definir una lista de preposiciones y superlativos
preposiciones <- c("a", "ante", "bajo", "cabe", "con", "contra", "de", "desde", "en", "entre", "hacia", "hasta", "para", "por", "según", "sin", "sobre", "tras", "durante", "mediante", "versus", "vía") # Agrega más preposiciones si es necesario
superlativos <- c("más", "mejor", "peor", "mayor", "menor", "tanto", "tan", "demasiado", "casi") # Agrega más superlativos si es necesario
# Función para limpiar el texto
limpiar_texto <- function(archivo) {
texto <- readLines(archivo, warn = FALSE)
texto <- paste(texto, collapse = " ")
# Eliminar puntuación
texto <- gsub("[[:punct:]]", "", texto)
# Eliminar preposiciones y superlativos
palabras <- unlist(strsplit(texto, " "))
palabras_filtradas <- palabras[!(palabras %in% c(preposiciones, superlativos))]
# Volver a unir las palabras filtradas
#texto_filtrado <- paste(palabras_filtradas, collapse = " ")
}
Para este procedimiento fue necesario hacerlo en dos etapas. La primera consiste en crear la función para que se eliminen las palabras especificas, pero como la función removeWords solo toma dos argumentos, en este caso el objeto (corpus_3) y las palabras a eliminar; la segunda etapa consiste en repetir el mismo procesamiento pero incluyendo a corpus_3 dentro de la instrucción tm_map, aplicando las tranformaicones del texto estructurado no solo de las palabras eliminadas manualmente, sino de las stopwords, creando así otra estructura de textos dtm_3
La matriz permite observar los terminos con sus respectivas frecuencias, posterior a ello se realizo un procedimiento basico de sumas totales y ordenamiento de texto para que mostrara las palabras más comunes ordenadas por la frecuencia en la que aparecen. Aunque el procesamiento de contar las columnas para obtener el conteo total de cada término parece un poco repetitivo, es indispensable para poder crear la dummy que utiliza el dataframe que despliega de manera ordenada las frecuencias de cada palabra. Como se puede observar a continución.
# Obtener la tabla de frecuencias de los términos
tabla_frecuencias <- table(conteo_total_3)
# Mostrar los términos más comunes junto con sus frecuencias
resultados <- data.frame(Termino = names(terminos_comunes_3),
Frecuencia = terminos_comunes_3,
Total = tabla_frecuencias[names(terminos_comunes_3)])
# Se despliega las primeras 100 palabras con mayor frecuencia
head(resultados, 100)
## Termino Frecuencia Total.conteo_total_3 Total.Freq
## méxico méxico 1575 <NA> NA
## gobierno gobierno 1415 <NA> NA
## gente gente 868 <NA> NA
## pueblo pueblo 827 <NA> NA
## pesos pesos 746 <NA> NA
## país país 667 <NA> NA
## tren tren 584 <NA> NA
## nacional nacional 572 <NA> NA
## prensa prensa 513 <NA> NA
## seguridad seguridad 496 <NA> NA
## presidencia presidencia 465 <NA> NA
## personas personas 454 <NA> NA
## salud salud 437 <NA> NA
## medios medios 435 <NA> NA
## unidos unidos 412 <NA> NA
## estenográfica estenográfica 406 <NA> NA
## ciudad ciudad 404 <NA> NA
## trabajo trabajo 398 <NA> NA
## maya maya 382 <NA> NA
## agua agua 377 <NA> NA
## zona zona 351 <NA> NA
## social social 346 <NA> NA
## dinero dinero 344 <NA> NA
## pública pública 338 <NA> NA
## federal federal 336 <NA> NA
## jóvenes jóvenes 335 <NA> NA
## república república 331 <NA> NA
## política política 326 <NA> NA
## libros libros 324 <NA> NA
## secretaría secretaría 312 <NA> NA
## intervención intervención 303 <NA> NA
## corrupción corrupción 292 <NA> NA
## trabajadores trabajadores 287 <NA> NA
## jesús jesús 285 <NA> NA
## proyecto proyecto 284 <NA> NA
## interlocutora interlocutora 275 <NA> NA
## ramírez ramírez 264 <NA> NA
## justicia justicia 259 <NA> NA
## problema problema 258 <NA> NA
## programa programa 258 <NA> NA
## transformación transformación 255 <NA> NA
## conocer conocer 252 <NA> NA
## gobernador gobernador 252 <NA> NA
## obra obra 251 <NA> NA
## difícil difícil 248 <NA> NA
## sociales sociales 248 <NA> NA
## violencia violencia 248 <NA> NA
## mundo mundo 246 <NA> NA
## pasado pasado 241 <NA> NA
## cuenta cuenta 240 <NA> NA
## mexicanos mexicanos 240 <NA> NA
## derecho derecho 239 <NA> NA
## obras obras 238 <NA> NA
## bienestar bienestar 237 <NA> NA
## centavos centavos 235 <NA> NA
## periodo periodo 234 <NA> NA
## apoyo apoyo 233 <NA> NA
## hablando hablando 232 <NA> NA
## hizo hizo 229 <NA> NA
## kilómetros kilómetros 229 <NA> NA
## sé sé 226 <NA> NA
## lang lang 225 <NA> NA
## properties properties 225 <NA> NA
## comisión comisión 223 <NA> NA
## iba iba 221 <NA> NA
## primero primero 218 <NA> NA
## reforma reforma 218 <NA> NA
## desarrollo desarrollo 217 <NA> NA
## falta falta 217 <NA> NA
## redes redes 217 <NA> NA
## mañana mañana 214 <NA> NA
## aeropuerto aeropuerto 213 <NA> NA
## chiapas chiapas 212 <NA> NA
## construcción construcción 212 <NA> NA
## trabajando trabajando 212 <NA> NA
## investigación investigación 211 <NA> NA
## primera primera 209 <NA> NA
## aunque aunque 208 <NA> NA
## mayoría mayoría 207 <NA> NA
## temas temas 207 <NA> NA
## tramo tramo 207 <NA> NA
## secretario secretario 205 <NA> NA
## precio precio 205 <NA> NA
## mes mes 204 <NA> NA
## claro claro 203 <NA> NA
## comunicación comunicación 203 <NA> NA
## hacia hacia 203 <NA> NA
## tipo tipo 203 <NA> NA
## seis seis 202 <NA> NA
## inversión inversión 201 <NA> NA
## quieren quieren 201 <NA> NA
## sistema sistema 201 <NA> NA
## campaña campaña 200 <NA> NA
## administración administración 199 <NA> NA
## decía decía 199 <NA> NA
## situación situación 199 <NA> NA
## hacen hacen 198 <NA> NA
## momento momento 197 <NA> NA
## julio julio 196 <NA> NA
## nunca nunca 196 <NA> NA
# Crear nueva nube de palabras
wordcloud(names(terminos_comunes_3),
terminos_comunes_3,
min.freq = 50, # frecuencia minima de las palabras
max.words = 100, # cuantas palabras caben en la nube
random.order = FALSE,
rot.per = 0.35,
#brewer.pal es una paleta de colores
colors = brewer.pal(6, "Paired"))
Se agrego {r, fig.width=10, fig.height=6} para extender la ventana interactiva del documento rmd así cabe más palabras dentro del gráfico visual.
Además se agregaron detalles para que se resaltaran las palabras más comunes con tamaños y colores distintos, de este modo se puede observar que México y presidente fueron las palabras más frecuentes pero las que están a su al rededor tienen un mismo contexto, el nacional. Esto quiere decir que las mañaneras, no solo es un espacio de divulgación sino un espacio para reproducir discursos con tintes nacionalistas e incluso populistas, hablando de progreso y de sectores economicos/sociales como un objeto dado en la nación y no como un área de oportunidad dentro del país. Apesar de que este procesamiento solo involucra la parte de la limpieza, a simple vista no parece haber adjetivos negativos que rodeen las palabras más frecuentes, México y gobierno.
#palabra que buscaras
palabra <- "corrupción" #No se pueden palabras compuestas, solo términos individuales
# Obtener el índice de la columna que corresponde a la palabra que buscas
indice_palabra <- which(colnames(dtm) == palabra)
# Si la palabra no se encuentra en la DTM, indice_palabra sera intiger(0)
if (length(indice_palabra) == 0) {
print(paste("La palabra", palabra, "no se ha mencionado en las conferencias mañaneras."))
} else {
#Obtener la columna que corresponde a esa palabra y sumarla para obtener el total de ocurrencias
frecuencia_total <- sum(as.matrix(dtm[, indice_palabra]))
print(paste("La palabra", palabra, "aparece", frecuencia_total, "veces en las conferencias mañaneras."))
}
## [1] "La palabra corrupción aparece 292 veces en las conferencias mañaneras."
# Tomar los 100 términos más comunes
terminos_top <- names(terminos_comunes_3)[1:50]
# Crear un vector con las frecuencias de estos términos
frecuencias_top <- terminos_comunes_3[1:50]
# Definir colores personalizados
colores <- colorRampPalette(brewer.pal(8, "Dark2"))(100)
# Crear un gráfico de barras con colores y ajustes de tamaño de letra
barplot(frecuencias_top,
names.arg = terminos_top,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados",
xlab = "Frecuencia",
col = colores, # Agregar los colores personalizados
border = "white", # Color de los bordes de las barras
cex.names = 0.5, # Tamaño de letra en el eje x
cex.axis = 0.9, # Tamaño de letra en los ejes
cex.main = 1.2, # Tamaño de letra en el título principal
cex.lab = 0.9 # Tamaño de letra en las etiquetas de los ejes
)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.2.3
##
## Attaching package: 'ggplot2'
## The following object is masked from 'package:NLP':
##
## annotate
# Convertir el resultado de las frecuencias en un data frame para la gráfica
df_frecuencias <- data.frame(Palabra = names(terminos_comunes_3), Frecuencia = terminos_comunes_3)
# Crear la gráfica de barras con colores diferentes para cada barra, ejes intercambiados y etiquetas en diagonal
ggplot(df_frecuencias[1:30, ], aes(x = Frecuencia, y = reorder(Palabra, -Frecuencia), fill = (Palabra))) +
geom_bar(stat = "identity") +
coord_flip() +
labs(x = "Frecuencia", y = "Palabra", title = "Palabras más frecuentes en las conferencias mañaneras") +
theme_classic() +
theme(axis.text.y = element_text(size = 10, color = "black"), # Ajustar tamaño y color del texto en el eje y
axis.text.x = element_text(angle = 45, hjust = 1, color = "black"), # Etiquetas en diagonal y color en el texto
legend.position = "bottom") # Colocar la leyenda en la parte inferior
Estos graficos muestran que efectivamente las palabras más frecuentes en las conferencias impartidas por el presidente Andrés Manuel Lopéz Obrador estaban encaminadas a un discurso politico con intereses polemicos que no cumplen con su objetivo principal de exponer los problemas de la Agenda Pública. Se utilizo distintas tecnicas de procesamiento de texto y visualizaciones de datos para llegar a lo mencionado anteriormente.
Uno de los principales hallazgos se encontro no en sus intereses personales, sino en el abuso de poder que contiene este espacio de comunicación, la infromación proporcionada estuve acorde a sus propios interese y a asuntos más discutidos durante el periodo del 1 de Junio 2023 al 24 de Agosto del mismo año. Estos procesamientos nos permiten establecer tendencias politicas y sociales sobre los asuntos nacionales, tambien ofrece una perpectiva unilateral sobre la opinón del presidente Andrés Manuel sobre lo que pasa en la cuidadania mexicana.