Primero comenzamos por abrir las librerías necesarias para realizar el análisis. Estas involucran librerías para crear gráficos, hacer el web scrapping y analizar el texto.
library(wordcloud)
## Loading required package: RColorBrewer
library(udpipe)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.0 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.1 ✔ tibble 3.1.8
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(tidytext)
library(dplyr)
library(sentimentr)
library(topicmodels)
library(tm)
## Loading required package: NLP
##
## Attaching package: 'NLP'
##
## The following object is masked from 'package:ggplot2':
##
## annotate
library(ggplot2)
library(readxl)
library(rvest)
##
## Attaching package: 'rvest'
##
## The following object is masked from 'package:readr':
##
## guess_encoding
library(textclean)
library(magrittr)
##
## Attaching package: 'magrittr'
##
## The following object is masked from 'package:purrr':
##
## set_names
##
## The following object is masked from 'package:tidyr':
##
## extract
library(igraph)
##
## Attaching package: 'igraph'
##
## The following objects are masked from 'package:lubridate':
##
## %--%, union
##
## The following objects are masked from 'package:dplyr':
##
## as_data_frame, groups, union
##
## The following objects are masked from 'package:purrr':
##
## compose, simplify
##
## The following object is masked from 'package:tidyr':
##
## crossing
##
## The following object is masked from 'package:tibble':
##
## as_data_frame
##
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
##
## The following object is masked from 'package:base':
##
## union
library(ggplot2)
library(syuzhet)
##
## Attaching package: 'syuzhet'
##
## The following object is masked from 'package:sentimentr':
##
## get_sentences
library(plotly)
##
## Attaching package: 'plotly'
##
## The following object is masked from 'package:igraph':
##
## groups
##
## The following object is masked from 'package:sentimentr':
##
## highlight
##
## The following object is masked from 'package:ggplot2':
##
## last_plot
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following object is masked from 'package:graphics':
##
## layout
Para facilitar la extracción de la información se creo un archivo de excel llamado “base_evidencia” en el que se contiene el año de publicación de la funete y su url. Esto con el fin de accesar y clasificar la información más facilmente. Para este proyecto se utilizaron 5 blogs por año.
La carga del archivo, así como su estructura se muestra a continuación.
links <- read_excel("base_evidencia.xlsx")
links
## # A tibble: 55 × 2
## Año Lga
## <dbl> <chr>
## 1 2023 https://nutricionportusalud.com/prediabetes-y-diabetes/
## 2 2023 https://nutricionportusalud.com/ejercicio-y-alimentacion/
## 3 2023 https://www.sofiasalud.com/blog/como-cuidar-tu-salud-fisica-y-mental-h…
## 4 2023 https://www.eltemplosaludable.com/salud/salud-fisica/
## 5 2023 https://www.casp.org.mx/post/10-hábitos-para-cuidar-la-salud-f%C3%ADsi…
## 6 2022 https://www.nationalgeographicla.com/familia/2022/10/7-habitos-saludab…
## 7 2022 https://www.psychologytoday.com/mx/blog/los-4-componentes-de-la-imagen…
## 8 2022 https://lamenteesmaravillosa.com/body-positive/
## 9 2022 https://www.vrim.com.mx/blog/wellness-equilibrio-saludable/tips-de-sal…
## 10 2022 https://blog.tecsalud.mx/wellness-el-equilibrio-entre-cuerpo-y-mente
## # ℹ 45 more rows
Después de esto, se descargaron los archivos identificados previamente en el documento de excel. Para esto se crearon 11 bucles, 1 por año analizado. Esto se debe a que al momento de realizar la extracciónn simultaneamente se se generaron el tiempo de la sesión expiraba y no se podía concluir la descarga. Se encontró que haciendo la extracción en bucles separados permitía descargar los archivos sin expirar la sesión.
n = 1 # Primero se define n como 1, esto servirá de contador más adelante.
for (i in 1:5) {
# Se lee la página a analizar que está dentro del data frame creado previamente.
pagina <- read_html(links$Lga[i])
# Se extraen los párrafos de las entradas de los blogs.
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
# Se crea el nombre del archivo con la secuencia "año-numero de archivo"
nombre_archivo <- paste0("2023-", n, ".txt")
# Finalmente, se escribe el contenido en un archivo txt para accesar al mismo facilmente.
writeLines(a, nombre_archivo)
n = n+1 # Al contador se le agrega 1 numero, este subirá hasta 5 y después será reiniciado en 1 con el fin de nombrar el archivo txt que se crea.
}
Esta misma secuencia se siguió para el resto de los años, lo cual se muestra a continuación.
n = 1
for (i in 6:10) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2022-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 11:15) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2021-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 16:20) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2020-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 21:25) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2019-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 26:30) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2018-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 31:35) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2017-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 36:40) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2016-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 41:45) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2015-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 46:50) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2014-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
n = 1
for (i in 51:55) {
pagina <- read_html(links$Lga[i])
parrafos.sc <- html_elements(pagina,"p")
a <- html_text(parrafos.sc)
nombre_archivo <- paste0("2013-", n, ".txt")
writeLines(a, nombre_archivo)
n = n+1
}
Para la limpieza de los datos se creo una función que toma como parametro la información del archivo a limpiar, realiza distintos procedimientos de limpieza y devuelve el texto limpio. Esto permite limpiar el texto de cualquier año sin necesidad de replicar el código de limpieza completamente.
Como parte del proceso de limpieza se probó lematizar los datos, sin embargo, esto generaba resultados sin sentido (por ejemplo, glucoso), por lo que se decidió eliminar del análisis.
limpiar_texto <- function(archivo) {
texto <- readLines(archivo, warn = FALSE)
texto <- paste(texto, collapse = " ")
# La función "tolower" convierte todo el texto a minúsculas para simplificar el análisis
texto <- tolower(texto)
# 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)
# Regresa el texto limpio
return(texto)
}
Primero se realizó un analisis para todos los años del estudio (2013-2023) con el fin de entender el panorama general de como se ha comprotado el discurso através de los años.
Para esto lo primero que se realizó fue extraer la información de todos los archivos que se descargaron previamente, limpiar la información disponible y generar el corpus y la matríz de documento-término. Después se obtuvieron los términos comunes de los 11 años.
# Se extraen todos los títulos archivos de txt encontrados en el entorno donde se guardó el archivo de R.
archivos <- list.files(pattern = "*.txt")
# En este caso, el archivo 5 del 2014 no contiene información después de la limpieza, entonces se removerá de la lista de archivos. Para esto se cambia en la lista de títulos el valor de "2014-5.txt" por un NA y posteriormente lo borra
archivos <- gsub("2014-5.txt", NA,archivos)
archivos <- na.omit(archivos)
# Aplica la función de limpieza a cada archivo
textos_limpios <- lapply(archivos, limpiar_texto)
# Crea el corpus linguistico, quita las stopwords y crea la matríz de documento término
corpus <- Corpus(VectorSource(textos_limpios))
corpus <- tm_map(corpus, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(corpus, removeWords, stopwords("es")):
## transformation drops documents
dtm <- DocumentTermMatrix(corpus)
# Hace una suma se las columnas de la matríz dtm para obtener las frecuencias totales de cada palabra
conteo_total <- colSums(as.matrix(dtm))
# Finalmente, utilizando las frecuencias totales de cada palabra se obtiene la lista de terminos comunes, con sus respectivas repeticiones.
terminos_comunes <- sort(conteo_total, decreasing = TRUE)
# Para vizualizar la información contenida en términos comunes se utilizó la función head, que permite ver los primeros n términos de un elemento. En este caso, se utilizó para ver los primeros 10 términos.
head(terminos_comunes, 10)
## salud ejercicio vida puede cuerpo física
## 256 168 152 149 145 135
## enfermedades personas ser actividad
## 103 100 93 90
Para visualizar las palabras más mencionadas se utilizó como primer método la nube de palabras. Esto porque la nube permite identificar las palabras más mencionadas de una forma muy visual y fácil de comprender. Asimismo, permite visualizar una alta cantidad de palabras sin perder legibilidad como en el caso de las gráficas.
# Para la nive de palabras se utilizó la función wordcloud, la cual utiliza los nombres extraídos de terminos_comunes, así como sus frecuencias.
wordcloud(names(terminos_comunes), terminos_comunes, min.freq = 30, max.words = 500, random.order = FALSE)
Posteriormente, se crea una gráfica de barras para visualizar la información relacionada con las frecuencias de palabras. Diferente a la nube de palabras, las gráficas de barras permiten ver la frecuencia con la que se dice, sin embargo, solo se pueden visualizar 10 terminos son comprometer la legibilidad de la gráfica.
# Crear un vector con las frecuencias de estos términos
frecuencias_top <- terminos_comunes[1:10]
barplot(frecuencias_top,
names.arg = names(frecuencias_top),
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2013-2023",
xlab = "Frecuencia",
col = "darkblue", # 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
)
Después, se analizaron los tópicos identificados atraves del tiempo. Para esto se utilizó la funcion tidy y se definió una k de 5 para identificar 5 tópicos. Una vez obtenidos los 5 tópicos, se realizó una gráfica para visualizar los 5 tópicos y sus términos.
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.gen <- LDA(dtm, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.gen, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
terms <- tidy(lda.gen, matrix = "beta")
terms <- terms %>%
select(term, beta)
Finalmente, se realizó un análisis de sentimientos para los años seleccionados. Esto se realizó con el diccionario de datos de nrc de la librería syuzhet. El análisis de sentimientos permite identificar la orientacion semantica de las palabras identificadas en el discurso con el fin de entender la emoción que representan.
Para esto se utilizó la variable textos_limpios, la cual contiene el texto limpio extraido previo a almacenarse en un vector. De igual forma, ya que la función get_nrc_sentiments solo acepta parametros de tipo char se utilizó la función as.character para poder introducir los datos en la funcion.
emotions <- get_nrc_sentiment(as.character(textos_limpios)) # Obtiene las emociones utilizando la librería nrc y convierte textos_limpios en char, estas se almacenan en un data frame llamado emotions.
emo_bar = colSums(emotions) # Suma las veces en las que una emoción se mencionó sumando los valores de las columnas del data frame y regresa una tabla donde indica las frecuencias de cada emoción, almacenada en emo_bar.
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar)) # Crea un data frame que contenga el nombre de la emoción y su frecuencia dados los datos proporcionados anteriormente.
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)]) # Ordena las emociones conforme a su frecuencia de mayor a menor y las almacena en emo_sum$emotion.
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>% # Se indica que se graficará el elemento emo_sum, donde el eje x son las emociones y el y su frecuencia. También se indica que el tipo de gráfica es de barras y que el color cambia según la emoción.
layout(xaxis=list(title=""), showlegend=FALSE, # Se indica que el título se mostrará por encima de la gráfica y que no tendrá leyendas.
title="Distribución de sentimientos, Sociedad civil 2013-2023")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
Este análisis se replicó para cada año de forma individual, con el fin de visualizar la forma en la que el discurso ha evolucionado através de los años. Esto se muestra a continuación.
# Se obtienen los nombres de todos los archivos txt generados previamente por año y se almacena en las variables arc_numero de año. Esto es equivalente a la variable archivos
arc_23 <- list.files(pattern = "2023-*")
arc_22 <- list.files(pattern = "2022-*")
arc_21 <- list.files(pattern = "2021-*")
arc_20 <- list.files(pattern = "2020-*")
arc_19 <- list.files(pattern = "2019-*")
arc_18<- list.files(pattern = "2018-*")
arc_17 <- list.files(pattern = "2017-*")
arc_16 <- list.files(pattern = "2016-*")
arc_15 <- list.files(pattern = "2015-*")
arc_14 <- list.files(pattern = "2014-*")
# En este caso, nuevamente se remueve el archivo 5 del 2014
arc_14 <- c("2014-1.txt", "2014-2.txt", "2014-3.txt", "2014-4.txt")
arc_13 <- list.files(pattern = "2013-*")
Posteriormente, se limpia el contenido de forma individual y se almnacena en las variables a.numero de año (por ejemplo, a.23 para 2023). Esta es equivalente a la variable textos_limpios
a.23 <- lapply(arc_23, limpiar_texto)
a.22 <- lapply(arc_22, limpiar_texto)
a.21 <- lapply(arc_21, limpiar_texto)
a.20 <- lapply(arc_20, limpiar_texto)
a.19 <- lapply(arc_19, limpiar_texto)
a.18 <- lapply(arc_18, limpiar_texto)
a.17 <- lapply(arc_17, limpiar_texto)
a.16 <- lapply(arc_16, limpiar_texto)
a.15 <- lapply(arc_15, limpiar_texto)
a.14 <- lapply(arc_14, limpiar_texto)
a.13 <- lapply(arc_13, limpiar_texto)
Despupes, se crean corpus linguisticos por año, los cuales se almacenan en las variables c.numero de año (por ejemplo, c.23 para 2023). Esta es equivalente a la variable corpus creada previamente.
c.23 <- Corpus(VectorSource(a.23))
c.22 <- Corpus(VectorSource(a.22))
c.21 <- Corpus(VectorSource(a.21))
c.20 <- Corpus(VectorSource(a.20))
c.19 <- Corpus(VectorSource(a.19))
c.18 <- Corpus(VectorSource(a.18))
c.17 <- Corpus(VectorSource(a.17))
c.16 <- Corpus(VectorSource(a.16))
c.15 <- Corpus(VectorSource(a.15))
c.14 <- Corpus(VectorSource(a.14))
c.13 <- Corpus(VectorSource(a.13))
Una vez generados los corpus, se les remueven las stopword como se hizo en el análisis general.
c.23 <- tm_map(c.23, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.23, removeWords, stopwords("es")):
## transformation drops documents
c.22 <- tm_map(c.22, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.22, removeWords, stopwords("es")):
## transformation drops documents
c.21 <- tm_map(c.21, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.21, removeWords, stopwords("es")):
## transformation drops documents
c.20 <- tm_map(c.20, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.20, removeWords, stopwords("es")):
## transformation drops documents
c.19 <- tm_map(c.19, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.19, removeWords, stopwords("es")):
## transformation drops documents
c.18 <- tm_map(c.18, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.18, removeWords, stopwords("es")):
## transformation drops documents
c.17 <- tm_map(c.17, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.17, removeWords, stopwords("es")):
## transformation drops documents
c.16 <- tm_map(c.16, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.16, removeWords, stopwords("es")):
## transformation drops documents
c.15 <- tm_map(c.15, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.15, removeWords, stopwords("es")):
## transformation drops documents
c.14 <- tm_map(c.14, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.14, removeWords, stopwords("es")):
## transformation drops documents
c.13 <- tm_map(c.13, removeWords, stopwords("es"))
## Warning in tm_map.SimpleCorpus(c.13, removeWords, stopwords("es")):
## transformation drops documents
Finalmente, se crean las matrices de termino-documento por año siguiendo la misma secuencia en el nombre de las variables.
dtm.23 <- DocumentTermMatrix(c.23)
dtm.22 <- DocumentTermMatrix(c.22)
dtm.21 <- DocumentTermMatrix(c.21)
dtm.20 <- DocumentTermMatrix(c.20)
dtm.19 <- DocumentTermMatrix(c.19)
dtm.18 <- DocumentTermMatrix(c.18)
dtm.17 <- DocumentTermMatrix(c.17)
dtm.16 <- DocumentTermMatrix(c.16)
dtm.15 <- DocumentTermMatrix(c.15)
dtm.14 <- DocumentTermMatrix(c.14)
dtm.13 <- DocumentTermMatrix(c.13)
Similar al análisis general, se obtienen los conteso totales y los terminos comunes para cada año utilizando la dtm y ordenandolos de mayor a menor frecuencia.
conteo_total.23 <- colSums(as.matrix(dtm.23))
conteo_total.22 <- colSums(as.matrix(dtm.22))
conteo_total.21 <- colSums(as.matrix(dtm.21))
conteo_total.20 <- colSums(as.matrix(dtm.20))
conteo_total.19 <- colSums(as.matrix(dtm.19))
conteo_total.18 <- colSums(as.matrix(dtm.18))
conteo_total.17 <- colSums(as.matrix(dtm.17))
conteo_total.16 <- colSums(as.matrix(dtm.16))
conteo_total.15 <- colSums(as.matrix(dtm.15))
conteo_total.14 <- colSums(as.matrix(dtm.14))
conteo_total.13 <- colSums(as.matrix(dtm.13))
terminos_comunes.23 <- sort(conteo_total.23, decreasing = TRUE)
terminos_comunes.22 <- sort(conteo_total.22, decreasing = TRUE)
terminos_comunes.21 <- sort(conteo_total.21, decreasing = TRUE)
terminos_comunes.20 <- sort(conteo_total.20, decreasing = TRUE)
terminos_comunes.19 <- sort(conteo_total.19, decreasing = TRUE)
terminos_comunes.18 <- sort(conteo_total.18, decreasing = TRUE)
terminos_comunes.17 <- sort(conteo_total.17, decreasing = TRUE)
terminos_comunes.16 <- sort(conteo_total.16, decreasing = TRUE)
terminos_comunes.15 <- sort(conteo_total.15, decreasing = TRUE)
terminos_comunes.14 <- sort(conteo_total.14, decreasing = TRUE)
terminos_comunes.13 <- sort(conteo_total.13, decreasing = TRUE)
Para comenzar a analizar los datos, se crearon nubes de palabras individuales para cada año. Estas se realizaron con los terminos comunes de cada año identificados previamente.
wordcloud(names(terminos_comunes.23), terminos_comunes.23, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.22), terminos_comunes.22, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.21), terminos_comunes.21, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.20), terminos_comunes.20, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.19), terminos_comunes.19, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.18), terminos_comunes.18, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.17), terminos_comunes.17, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.16), terminos_comunes.16, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.15), terminos_comunes.15, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.14), terminos_comunes.14, min.freq = 10, max.words = 500, random.order = FALSE)
wordcloud(names(terminos_comunes.13), terminos_comunes.13, min.freq = 10, max.words = 500, random.order = FALSE)
Asimismo, se realizaron gráficas de frecuencia utilizando los 10 terminos más comunes por año.
# Tomar los 10 términos más comunes
terminos_top.23 <- names(terminos_comunes.23)[1:10]
terminos_top.22 <- names(terminos_comunes.22)[1:10]
terminos_top.21 <- names(terminos_comunes.21)[1:10]
terminos_top.20 <- names(terminos_comunes.20)[1:10]
terminos_top.19 <- names(terminos_comunes.19)[1:10]
terminos_top.18 <- names(terminos_comunes.18)[1:10]
terminos_top.17 <- names(terminos_comunes.17)[1:10]
terminos_top.16 <- names(terminos_comunes.16)[1:10]
terminos_top.15 <- names(terminos_comunes.15)[1:10]
terminos_top.14 <- names(terminos_comunes.14)[1:10]
terminos_top.13 <- names(terminos_comunes.13)[1:10]
# Crear un vector con las frecuencias de estos términos
frecuencias_top.23 <- terminos_comunes.23[1:10]
frecuencias_top.22 <- terminos_comunes.22[1:10]
frecuencias_top.21 <- terminos_comunes.21[1:10]
frecuencias_top.20 <- terminos_comunes.20[1:10]
frecuencias_top.19 <- terminos_comunes.19[1:10]
frecuencias_top.18 <- terminos_comunes.18[1:10]
frecuencias_top.17 <- terminos_comunes.17[1:10]
frecuencias_top.16 <- terminos_comunes.16[1:10]
frecuencias_top.15 <- terminos_comunes.15[1:10]
frecuencias_top.14 <- terminos_comunes.14[1:10]
frecuencias_top.13 <- terminos_comunes.13[1:10]
# 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.23,
names.arg = terminos_top.23,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2023",
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
)
barplot(frecuencias_top.22,
names.arg = terminos_top.22,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2022",
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
)
barplot(frecuencias_top.21,
names.arg = terminos_top.21,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2021",
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
)
barplot(frecuencias_top.20,
names.arg = terminos_top.20,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2020",
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
)
barplot(frecuencias_top.19,
names.arg = terminos_top.19,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2019",
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
)
barplot(frecuencias_top.18,
names.arg = terminos_top.18,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2018",
xlab = "Frecuencia",
col = colores, # Agregar los colores personalizados
border = "white", # Color de los bordes de las barras
cex.names = , # Tamaño de letra en el eje x
cex.axis = 2, # 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
)
barplot(frecuencias_top.17,
names.arg = terminos_top.17,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2017",
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
)
barplot(frecuencias_top.16,
names.arg = terminos_top.16,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2016",
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
)
barplot(frecuencias_top.15,
names.arg = terminos_top.15,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2015",
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
)
barplot(frecuencias_top.14,
names.arg = terminos_top.14,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2014",
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
)
barplot(frecuencias_top.13,
names.arg = terminos_top.13,
horiz = TRUE,
las = 1,
main = "Términos Más Utilizados 2013",
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
)
Después de esto, se realizó el modelado de tópicos para cada año utilizando sus dtms correspondientes.
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.23 <- LDA(dtm.23, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.23, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.22 <- LDA(dtm.22, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.22, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.21 <- LDA(dtm.21, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.21, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.20 <- LDA(dtm.20, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.20, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.19 <- LDA(dtm.19, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.19, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.18 <- LDA(dtm.18, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.18, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.17 <- LDA(dtm.17, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.23, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.17 <- LDA(dtm.17, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.23, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.16 <- LDA(dtm.16, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.16, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.15 <- LDA(dtm.15, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.15, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.14 <- LDA(dtm.14, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.14, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
# Generar un modelo de topic models (Modelos de aprendizaje no supervisado)
lda.13 <- LDA(dtm.13, k = 5)
# Obtener los términos más importantes de cada tópico
terms <- tidy(lda.13, matrix = "beta") %>%
group_by(topic) %>%
top_n(3, wt = beta)
# Generar el gráfico
ggplot(terms, aes(x = term, y = beta, fill = topic)) +
geom_col(show.legend = FALSE) +
coord_flip() +
facet_wrap(~topic, ncol = 3)
Finalmente, se realizaron los análisis de sentimientos para cada año. Esto se hizo utilizando el mismo procedimiento que en el análisis general, así como la misma librería y diccionaro. En este caso, en lugar de archivos se utilizaron las variables a.numero de año (por ejemplo, a.23) y de la misma forma se pasaron a caracteres que después se procesaron. Este procedimiento de muestra a continuación.
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.23))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2023 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.22))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2022 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.21))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2021 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.20))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2020 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.19))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2019 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.18))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2018 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.17))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2017 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.16))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2016 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.15))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2015 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.14))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2014 ")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
# get the emotions using the NRC dictionary
emotions <- get_nrc_sentiment(as.character(a.13))
emo_bar = colSums(emotions)
emo_sum = data.frame(count=emo_bar, emotion=names(emo_bar))
emo_sum$emotion = factor(emo_sum$emotion, levels=emo_sum$emotion[order(emo_sum$count, decreasing = TRUE)])
# Visualización
plot_ly(emo_sum, x=~emotion, y=~count, type="bar", color=~emotion) %>%
layout(xaxis=list(title=""), showlegend=FALSE,
title="Distribución de sentimientos, Sociedad civil 2013")
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors