#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))