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)
#url <- "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-del-presidente-andres-manuel-lopez-obrador-del-9-de-agosto-de-2023"
#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 operacioens 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 gurdando 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 extraímos 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 elemntos 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)
###Función para hacer el webscraping y guardar en archivo .txt *NUEVA VARIABLE
#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
# 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 <div class="contenido-conferencia">
# (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")
#Eliminar sitio en mantenimiento
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 cieeto 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
#Limpieza
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 incluímos 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 prevuiamente 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 alamacenados 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)
###textos_limpios[1]
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 represnetan 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 cocumentos ahora tendrán forma de matriz.La DTM se utiliza para realizar análisis de un texto.
library(tm)
## 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: 27300)>>
## Non-/sparse entries: 137961/1090539
## Sparsity : 89%
## Maximal term length: 605
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs con del las los para pero por presidente que una
## 1 122 143 118 255 123 121 161 168 642 131
## 18 156 174 92 273 166 74 169 91 570 152
## 25 166 160 103 297 133 65 136 127 571 94
## 27 155 139 90 296 144 110 129 65 623 97
## 37 182 194 145 244 173 67 160 118 656 145
## 38 241 256 129 217 178 68 165 93 623 125
## 42 148 162 97 243 143 104 129 138 713 97
## 43 148 131 103 356 142 109 164 110 721 136
## 44 148 131 103 356 142 109 164 110 721 136
## 6 173 154 105 246 144 89 163 129 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 realizarel proceso anterior. Raeliza un ordenamiento drecreciente 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 docuemntos 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 palbras 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.
#Hagamos un poco más de análisis
# 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 6358 5677 5491 5066 4353
## una las pero porque más como lópez
## 4270 4156 3343 3216 3052 2710 2630
## manuel andrés también hay eso está muy
## 2584 2545 2484 2424 2282 2222 2141
## este var sí obrador entonces todo mil
## 2059 2025 1982 1849 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)
## 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, rot.per = 0.35, colors = brewer.pal(8, "Dark2"))
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
###STOPWPRDS
Las stopwords 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 búsqueda, estas 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: 26479)>>
## Non-/sparse entries: 131435/1060120
## Sparsity : 89%
## Maximal term length: 605
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs andrés entonces lópez manuel méxico mil obrador presidente vamos var
## 1 110 47 113 109 35 43 109 168 23 45
## 16 34 25 35 38 94 64 34 90 46 45
## 18 41 43 42 43 44 45 8 91 49 45
## 25 69 32 71 69 33 91 69 127 34 45
## 37 73 30 76 76 24 55 10 118 33 45
## 38 54 46 54 58 41 40 13 93 45 45
## 42 85 101 89 95 30 31 9 138 39 45
## 43 82 64 86 82 55 33 84 110 50 45
## 44 82 64 86 82 55 33 84 110 50 45
## 6 65 42 65 60 28 25 8 129 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
## 4353 2630 2584 2545 2025
## obrador entonces mil vamos méxico
## 1849 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ías 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 constantes en cada mañanera.
Para esta limpieza, no solo se necesitan eliminar las palabras nulas, sino también las palabras que no aportan ningún valor a la conversación o conferencia; ejemplos de estas son presidente, Andrés Manuel o aquellas que suelen estar asociadas a la descripción de un objeto o cifra, como cien o mil, etc.
NOTA: Antes de hacer esta limpieza, es necesario mostrar qué palabras son las que más se repiten para poder realizar la limpieza de manera efectiva. Una forma de hacerlo es a través de una gráfica o algún 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"))
Si hay palabras especificas que deseas eliminar en tu análisis, puedes hacer una lista de estas palabras y removerlas.
Como se puede observar, las palabras que más se repiten están de un tamaño más grande y de un color distinto, lo que corresponde a la frecuencia en comparación con 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 encuentren en su frecuencia máxima debido a la extensión de la misma. Algunas de las palabras que no se muestran debido a su extensión son:
Desarrollo Investigación Dinero Transformación Derechos Estas palabras resultan importantes para un análisis posterior, por lo que no pueden quedar fuera del gráfico. Para ello, será necesario crear la tabla de frecuencias 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 4353 <NA> NA
## lópez lópez 2630 <NA> NA
## manuel manuel 2584 <NA> NA
## andrés andrés 2545 <NA> NA
## var var 2025 <NA> NA
## obrador obrador 1849 <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
## 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
## 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
## prensa prensa 423 <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
## conferencia conferencia 394 <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 énfasis 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 políticas, 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: 26113)>>
## Non-/sparse entries: 125381/1049704
## Sparsity : 89%
## Maximal term length: 605
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs gente gobierno méxico nacional país pesos presidencia pueblo seguridad
## 1 13 32 35 8 22 24 9 8 8
## 16 19 40 94 6 16 14 11 5 11
## 18 18 25 44 18 15 41 9 10 5
## 25 22 25 33 28 15 25 11 7 24
## 37 32 35 24 23 24 40 11 18 14
## 38 29 50 41 17 26 39 9 15 5
## 42 24 35 30 13 15 7 15 29 15
## 43 39 28 55 4 16 7 9 51 1
## 44 39 28 55 4 16 7 9 51 1
## 6 23 28 28 17 16 36 13 36 6
## Terms
## Docs tren
## 1 1
## 16 44
## 18 38
## 25 6
## 37 64
## 38 62
## 42 4
## 43 0
## 44 0
## 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 transformaciones 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 términos 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 continuació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
## 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
## prensa prensa 423 <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
## jóvenes jóvenes 335 <NA> NA
## república república 331 <NA> NA
## bienestar bienestar 327 <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
## federal federal 291 <NA> NA
## trabajadores trabajadores 287 <NA> NA
## jesús jesús 285 <NA> NA
## proyecto proyecto 284 <NA> NA
## programas programas 278 <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
## 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
## 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"))
Además, se agregaron detalles para resaltar 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 alrededor tienen un mismo contexto, el nacional. Esto significa que las mañaneras no solo son un espacio de divulgación, sino también un lugar para reproducir discursos con tintes nacionalistas e incluso populistas. Se habla de progreso y de sectores económicos/sociales como un objeto dado en la nación y no como un área de oportunidad dentro del país. A pesar 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 <- "claudia" #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 claudia aparece 32 veces en las conferencias mañaneras."
#Gráfica de frecuencias
Para representar la frecuencia de las palabras, realizaremos una gráfica de frecuencias para conocer las palabras más repetidas en las mañaneras. Las palabras más repetidas fueron “méxico” y “gobierno”. En el eje y pusimos las palabras y en el x pusimos la frecuencia. Acomodamos las palabras en orden descendente e igual le pusimos colores para que fuera más atractiva a la vista.
# 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
)
Esta es otra forma de graficar realizaremos un ggplot para graficar la frecuencia de las palabras más utilizadas. Las palabras más repetidas fueron “méxico” y “gobierno”. Inlcuimos una leyenda con una palabra por color para que fuera más facil de interpretar y visualizar. Se acomodaron por frecuencia, de mayor a menor.
library(ggplot2)
##
## 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
#Conclusión En este código realizamos un análisis de la frecuencia de las palabras en las mañaneras del presidente Andrés Manuel López Obrador durante el periodo del 1 de junio al 24 de agosto del presente año. Para realizar este análisis hemos utilizado diversos comando para realizar operaciones que nos serían útiles como la limpieza de los archivos. Hemos identificado una serie de palbras más repetidas dentro de las mañaneras, lo cuál nos puede transmitir distintos mensajes como los temas de interés del presidente y nos permite realizar futuros procedimientos y análisis. Observamos que las palabras más frecuentes fueron “méxico” y “gobierno”. Para representar sto, hemos realizado disnitntas visualizaciones como tablas de frecuencias, nubes de palabras, gráficas de frecuencias y ggplot que nos permitieron plasmar nuetsros resultados de una manera más visible y clara. Eventualmente, esto nos puede ayudar a identificar tendencias o cambios en el dicurso del presidente. En conclusión, esto nos permite identificar los temas de interés dentro de la agenda presidencial.