#Este chunk está comentado ya que solo funciona para extraer el txt de una sola liga (en este caso de una sola mañanera). Sin embargo, para esta actividad, queremos descargar distinos urls, por lo que se seguirá otro procedimiento
#Desgargamos las librerias necesarias para extraer un texto de una liga
#library(rvest)
#library(magrittr)
#Posteriormente, creamos una variable "url" con la liga que se analizará
#url <- "https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-del-presidente-andres-manuel-lopez-obrador-del-9-de-agosto-de-2023"
#Creamos una variable "página", a la que le atribuimos la función read_html para extraer el texto
#pagina <- read_html(url)
# Remplazamos "XPATH_o_CSS_selector" con el selector adecuado
#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)
Definición de las fechas de las mañaneras y webscraping para obtener
los datos
'#Definimos las fechas de las mañaneras que queremos analizar y las guardamos como variable "fechas"
fechas <- seq.Date(as.Date("2023-01-01"), as.Date("2023-08-24"), by="days")
#Descargamos las librerías necesarias
library(rvest)
library(magrittr)
# Creamos la función para hacer el webscraping y guardar en archivo .txt
scrape_y_guarda <- function(fecha) {
# Cambiamos el idioma a español para asegurarnos que corra correctamente la función
Sys.setlocale("LC_TIME", "es_ES.UTF-8")
# Creamos un formato de la fecha para la URL
dia <- as.numeric(format(fecha, "%d"))
mes <- format(fecha, "%B")
ano <- format(fecha, "%Y")
fecha_url <- paste(dia, "de", mes, "de", ano, sep="-")
#Definimos la función url, que utilizará las variables creadas de la fecha para descargar las mañaneras del rango de fechas deseado
url <- paste0("https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-del-presidente-andres-manuel-lopez-obrador-del-", fecha_url)
# Creamos 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()
# Creamos el nombre deseado para el archivo y lo guarda en la carpeta en donde se encuentra el archivo rmd
nombre_archivo <- paste0("conferencia_", gsub("-de-", "_", fecha_url), ".txt")
writeLines(texto, nombre_archivo)
}
#Función para extrar el texto y guardarlo en la carpeta especificada
lapply(fechas, scrape_y_guarda)'
## [1] "#Definimos las fechas de las mañaneras que queremos analizar y las guardamos como variable \"fechas\"\nfechas <- seq.Date(as.Date(\"2023-01-01\"), as.Date(\"2023-08-24\"), by=\"days\")\n\n#Descargamos las librerías necesarias\nlibrary(rvest)\nlibrary(magrittr)\n\n# Creamos la función para hacer el webscraping y guardar en archivo .txt\nscrape_y_guarda <- function(fecha) {\n \n # Cambiamos el idioma a español para asegurarnos que corra correctamente la función\n Sys.setlocale(\"LC_TIME\", \"es_ES.UTF-8\")\n # Creamos un formato de la fecha para la URL\n dia <- as.numeric(format(fecha, \"%d\"))\n mes <- format(fecha, \"%B\")\n ano <- format(fecha, \"%Y\")\n fecha_url <- paste(dia, \"de\", mes, \"de\", ano, sep=\"-\")\n \n #Definimos la función url, que utilizará las variables creadas de la fecha para descargar las mañaneras del rango de fechas deseado\n \n url <- paste0(\"https://www.gob.mx/presidencia/articulos/version-estenografica-conferencia-de-prensa-del-presidente-andres-manuel-lopez-obrador-del-\", fecha_url)\n \n# Creamos el webscraping\n pagina <- read_html(url)\n \n # Suponiendo que el contenido de la conferencia está en un selector específico, como <div class=\"contenido-conferencia\"> \n # (es necesario verificar y ajustar este selector de acuerdo al código fuente real de la página)\n texto <- pagina %>%\n #html_nodes(\".contenido-conferencia\") %>% # <-- reemplaza \".contenido-conferencia\" con el selector CSS correcto\n html_text()\n \n # Creamos el nombre deseado para el archivo y lo guarda en la carpeta en donde se encuentra el archivo rmd\n nombre_archivo <- paste0(\"conferencia_\", gsub(\"-de-\", \"_\", fecha_url), \".txt\")\n writeLines(texto, nombre_archivo)\n}\n\n#Función para extrar el texto y guardarlo en la carpeta especificada\nlapply(fechas, scrape_y_guarda)"
Limpieza de los archivos sin contenido
#Eliminamos los archivos que no tienen contenido, sino que leen "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.
#Enlistamos los archivos existentes que descargamos anteriormente
archivos <- list.files(pattern = "*.txt"
)
# Función para verificar y eliminar archivos no deseados
verificar_y_eliminar <- function(archivo) {
#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)
#¡Esta función concatena el vector de líneas (anteriormente leído) en un solo string.
texto <- paste(texto, collapse = " ")
# Si el archivo contiene "Sitio en mantenimiento", se elimina. Es decir, si encuentra el texto ingresado, devuelve TRUE y elimina el txt; de lo contrario, devuelve FALSE.
#ignore.case = TRUE: Ignora la diferencia entre mayúsculas y minúsculas al buscar la cadena, asi nos aseguramos de que no queden algunos textos sin eliminar
if (grepl("Sitio en mantenimiento", texto, ignore.case = TRUE)) {
file.remove(archivo)
cat(paste("Archivo eliminado:", archivo, "\n"))
}
}
# 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
##
## [[46]]
## NULL
##
## [[47]]
## NULL
##
## [[48]]
## NULL
##
## [[49]]
## NULL
##
## [[50]]
## NULL
##
## [[51]]
## NULL
##
## [[52]]
## NULL
##
## [[53]]
## NULL
##
## [[54]]
## NULL
##
## [[55]]
## NULL
##
## [[56]]
## NULL
##
## [[57]]
## NULL
##
## [[58]]
## NULL
##
## [[59]]
## NULL
##
## [[60]]
## NULL
##
## [[61]]
## NULL
##
## [[62]]
## NULL
##
## [[63]]
## NULL
##
## [[64]]
## NULL
##
## [[65]]
## NULL
##
## [[66]]
## NULL
##
## [[67]]
## NULL
##
## [[68]]
## NULL
##
## [[69]]
## NULL
##
## [[70]]
## NULL
##
## [[71]]
## NULL
##
## [[72]]
## NULL
##
## [[73]]
## NULL
##
## [[74]]
## NULL
##
## [[75]]
## NULL
##
## [[76]]
## NULL
##
## [[77]]
## NULL
##
## [[78]]
## NULL
##
## [[79]]
## NULL
##
## [[80]]
## NULL
##
## [[81]]
## NULL
##
## [[82]]
## NULL
Limpieza de los datos
# Enlistamos los archivos txt existentes en nuestra carpeta (los que no fueron eliminados) y se guardan en el vector "archivos"
archivos <- list.files(pattern = "*.txt")
# Función para limpiar el texto
limpiar_texto <- function(archivo) {
texto <- readLines(archivo, warn = FALSE)
texto <- paste(texto, collapse = " ")
# Esta función sa una expresión regular para encontrar URLs que comiencen con "http" o "www" para eliminar estos caracteres
texto <- gsub("http\\S+|www\\.\\S+", "", texto)
# Esta funcion sirve para eliminar etiquetas HTML (si las hubiera): gsub("<.*?>", "", texto)
texto <- gsub("<.*?>", "", texto)
# Elimina cualquier carácter de puntuación del texto.
texto <- gsub("[[:punct:]]", "", texto)
# Eliminar números: gsub("\d+", "", texto)
texto <- gsub("\\d+", "", texto)
# Eliminar espacios extra: gsub("\s+", " ", texto):
texto <- gsub("\\s+", " ", texto)
# La función "tolower" convierte todo el texto a minúsculas para simplificar el análisis
texto <- tolower(texto)
return(texto)
}
# Aplicar la función de limpieza a cada archivo
textos_limpios <- lapply(archivos, limpiar_texto)
Analisis de la información
#cargamos la biblioteca para el analisis del texto limpio (tm)
library(tm)
## Loading required package: NLP
#Se crea un corpus con textos limpios
corpus<-Corpus(VectorSource(textos_limpios))
#Creamos una matriz con los textos
dtm <- DocumentTermMatrix(corpus)
#Función para analizar la matriz y obtener datos relevantes
inspect(dtm)
## <<DocumentTermMatrix (documents: 82, terms: 35202)>>
## Non-/sparse entries: 229870/2656694
## Sparsity : 92%
## Maximal term length: 601
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs con del las los más para por presidente que una
## 16 127 164 115 223 98 98 230 145 599 77
## 22 162 165 130 216 98 148 131 108 647 129
## 23 238 196 181 285 108 137 159 106 630 122
## 29 211 229 125 240 107 165 167 115 608 137
## 37 256 307 156 266 82 202 169 88 618 185
## 39 140 205 95 262 76 111 180 116 570 107
## 56 161 141 129 209 99 136 176 110 717 130
## 57 166 198 165 279 71 114 186 92 673 136
## 63 202 224 120 239 112 153 162 87 674 139
## 73 156 186 115 252 67 145 148 147 599 126
#Contamos las palabras del primer documento
conteo_primer_doc <- as.matrix(dtm[1,])
#sort(conteo_primer_doc, decreasing = TRUE)
#Sumar las columnas para obtener el conteo total de cada término
conteo_total <- colSums(as.matrix(dtm))
#ordenar y mostrar los terminos mas comunes
terminos_comunes <- sort(conteo_total, decreasing =TRUE)
head(terminos_comunes, 50) #Mostrar los 50 terminos mas comunes
## que los del con por para presidente
## 38256 14379 11537 9792 9323 8169 7473
## las una más pero porque lópez como
## 7447 7007 4989 4927 4841 4466 4361
## manuel andrés también hay este está var
## 4163 4140 3891 3792 3739 3702 3465
## eso mil muy entonces obrador qué méxico
## 3407 3322 3136 3013 2940 2850 2749
## sí son todo vamos esta esto nos
## 2746 2680 2630 2553 2446 2410 2319
## tiene gobierno aquí pues fue están todos
## 2309 2283 2254 2178 2033 2024 2008
## dimension tenemos ver bueno sobre estados dos
## 1925 1846 1811 1795 1795 1693 1692
## ahí
## 1687
#Instalar y cargar el paquete wordcloud
library(wordcloud)
## Loading required package: RColorBrewer
#creamos la nube de palabras para representar de manera visual
wordcloud(names(terminos_comunes), terminos_comunes, min.freq =5, max.words = 100, random.order = FALSE)

#Es importante notar que esta nube muestra algunos terminos que no son relevantes para el analisis, y deberán filtrarse después
#Eliminar stopwords de nuestro corpus (muletillas)
corpus <- tm_map(corpus, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(corpus, removeWords, stopwords("es")):
## transformation drops documents
#Se repite el análisis para crear la nube con las palabras filtradas
dtm <- DocumentTermMatrix(corpus)
conteo_primer_doc <- as.matrix(dtm[1,])
#sort(conteo_primer_doc, decreasing = TRUE)
#Sumar las columnas para obtener el conteo total de cada término
conteo_total <- colSums(as.matrix(dtm))
#ordenar y mostrar los terminos mas comunes
terminos_comunes <- sort(conteo_total, decreasing =TRUE)
head(terminos_comunes, 50) #Mostrar los 50 terminos mas comunes
## presidente lópez manuel andrés var
## 7473 4466 4163 4140 3465
## mil entonces obrador méxico vamos
## 3322 3013 2940 2749 2553
## gobierno aquí pues dimension ver
## 2283 2254 2178 1925 1811
## bueno dos ahí ahora millones
## 1795 1692 1687 1573 1541
## nacional cómo caso pesos país
## 1471 1448 1391 1390 1321
## function ciento unidos así null
## 1309 1276 1270 1266 1232
## seguridad señor pagetype tres información
## 1201 1159 1155 1146 1130
## usted días ser van pueblo
## 1121 1097 1093 1084 1080
## gagobtrackerset bien años gente hacer
## 1078 1074 1071 1065 1049
## año parte prensa tema hace
## 1023 1001 999 967 962
wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 5, max.words = 100, random.order = FALSE)

#inspeccionamos la matriz de la nube anterior. Con esta, podemos obervar cuales son os terminos más repetidos en las mañaneras.
inspect(dtm)
## <<DocumentTermMatrix (documents: 82, terms: 33982)>>
## Non-/sparse entries: 218640/2567884
## Sparsity : 92%
## Maximal term length: 601
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs andrés entonces lópez manuel méxico mil obrador presidente vamos var
## 16 68 42 73 68 30 42 70 145 28 45
## 22 66 39 66 66 52 76 66 108 53 45
## 23 54 24 54 56 47 50 10 106 60 45
## 29 62 39 61 62 65 89 55 115 32 45
## 37 46 47 47 46 86 64 47 88 37 45
## 39 59 48 61 60 49 114 59 116 31 45
## 56 70 67 70 70 52 47 70 110 43 45
## 57 37 43 37 37 53 28 11 92 26 45
## 63 48 27 47 50 48 65 47 87 49 45
## 73 79 58 82 79 46 85 11 147 49 45
Eliminamos palabras específicas que no sean relevantes para el
análisis
palabras_eliminar <- c("null", "gtagset", "presidente", "var", "pagetype", "andrés", "manuel", "lópez", "obrador", "bueno", "entonces", "interlocutor", "estenográfica", "pues", "gagobtrackerset" )
corpus <- tm_map(corpus, removeWords, palabras_eliminar)
## Warning in tm_map.SimpleCorpus(corpus, removeWords, palabras_eliminar):
## transformation drops documents
#repetir el proceso con las palabras reducidas. (creamos la matriz, contamos las veces que se repiten los terminos y los ordenamos de mayor número de veces repetidas a menos)
dtm <- DocumentTermMatrix(corpus)
conteo_primer_doc <- as.matrix(dtm[1,])
#sort(conteo_primer_doc, decreasing = TRUE)
#Sumar las columnas para obtener el conteo total de cada término
conteo_total <- colSums(as.matrix(dtm))
#ordenar y mostrar los terminos mas comunes
terminos_comunes <- sort(conteo_total, decreasing =TRUE)
head(terminos_comunes, 50) #Mostrar los 50 terminos mas comunes
## mil méxico vamos gobierno aquí dimension
## 3322 2749 2553 2283 2254 1925
## ver dos ahí ahora millones nacional
## 1811 1692 1687 1573 1541 1471
## cómo caso pesos país function ciento
## 1448 1391 1390 1321 1309 1276
## unidos así seguridad señor tres información
## 1270 1266 1201 1159 1146 1130
## usted días ser van pueblo bien
## 1121 1097 1093 1084 1080 1074
## años gente hacer año parte prensa
## 1071 1065 1049 1023 1001 999
## tema hace garcía poder importante conferencia
## 967 962 952 905 898 884
## puede hoy día además manera mismo
## 873 866 855 846 845 829
## luna decir
## 826 816
inspect(dtm)
## <<DocumentTermMatrix (documents: 82, terms: 33858)>>
## Non-/sparse entries: 217254/2559102
## Sparsity : 92%
## Maximal term length: 601
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs ahí ahora aquí dimension dos gobierno méxico mil vamos ver
## 16 46 22 29 25 26 33 30 42 28 30
## 22 29 33 37 25 38 24 52 76 53 35
## 23 14 19 25 25 24 32 47 50 60 38
## 29 17 34 35 25 36 35 65 89 32 32
## 37 31 26 23 25 31 45 86 64 37 25
## 39 20 27 50 25 39 28 49 114 31 27
## 56 24 33 28 25 27 49 52 47 43 31
## 57 20 20 35 25 20 39 53 28 26 23
## 63 22 19 16 25 36 30 48 65 49 28
## 73 32 13 32 25 51 28 46 85 49 29
#Creamos una nube de palabras con los resultados
wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10, max.words = 100, random.order = FALSE)
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : corrupción could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : secretario could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : siempre could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : pagesgroup could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : guardia could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : acuerdo could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : política could not be fit on page. It will not be plotted.
## Warning in wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 10,
## : programa could not be fit on page. It will not be plotted.

#Funciones para buscar la frecuencia de una palabra en específico
#palabra <- "algodón"
#indice_palabra <- which(colnames(dtm)== palabra)
#Si la palabra no se encuentra en la DTM, , indice_palabra será integer(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."))
#}
Visualización en gráfica de barras
# En esta parte del codigo, se genera un data frame que contiene los 20 terminos más comunes utilizados en las mañaneras, por lo que primero se extraen dichos terminos y después de almacenan en el data frame df_terminos_comunes.
top_terminos <- head(terminos_comunes, 20)
df_terminos_comunes <- data.frame(Palabra = names(top_terminos),
Frecuencia = top_terminos)
# Después, se utiliza la librería ggplot2 para generar una gráfica de barras en donde se muestren en las 20 palabras más utilizadas y las veces que se han utilizado. Esto para visualizar de forma más precisa la información.
library(ggplot2)
##
## Attaching package: 'ggplot2'
## The following object is masked from 'package:NLP':
##
## annotate
ggplot(df_terminos_comunes, aes(x = reorder(Palabra, -Frecuencia), y = Frecuencia)) +
geom_bar(stat = "identity") +
labs(title = "Frecuencia de las 20 Palabras Más Comunes",
x = "Palabra",
y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
