-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathversionfinal.Rmd
591 lines (437 loc) · 26.6 KB
/
versionfinal.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
---
output:
word_document:
toc: true
fig_width: 7
fig_height: 5
fig_caption: true
toc: true
---
```{r librerias1, include=FALSE}
library(tidyverse)
library(lubridate)
library(ggthemes)
library(hrbrthemes)
library(scales)
library(ggsci)
library(kableExtra)
import_roboto_condensed()
```
# Análisis Exploratorio de Datos sobre las publicaciones que usa el término "Presirvienta" en la red social "X"
Por: Lic. Juan Carlos Baena Silva, MH
Candidato a doctor en Humanidades, miembro fundador del Colectivo de Investigación Transvectorial (CIT)
## Introducción
Los primeros días de la presidencia de Claudia Sheinbaum han estado marcados por expresiones de discriminación y misoginia en redes sociales. Destaca el uso del término despectivo "Presirvienta", una expresión que combina misoginia y clasismo al intentar descalificar a la mandataria. Esta narrativa discriminatoria tuvo un momento importante en junio de 2024, cuando el actor Rafael Inclán declaró: "Ahora vamos a tener una ama de casa seis años".[^1] Ante estos señalamientos, Claudia Sheinbaum respondió el 3 de octubre enfatizando que el término "sirvienta" es misógino y defendió un principio fundamental: la dignidad inherente a todo trabajo.[^2]
[^1]: <https://lacaderadeeva.com/voces/misoginia-politica-ataques-a-sheinbaum-en-sus-primeros-dias/11509>
[^2]: <https://es-us.vida-estilo.yahoo.com/critican-actor-comentario-mis%C3%B3gino-sheinbaum-093226184.html>
Para entender el discurso e impacto de las publicaciones que nombran a la presidenta de manera despectiva, a continuación se presenta un análisis exploratorio de los datos obtenidos sobre los tuits que incluyeran la palabra "Presirvienta", entre el 1 de octubre del 2024 y el 8 del mismo mes. Se presentan algunas gráficas y la interpretación de las mismas buscando analizar los contenidos y los comportamientos de publicación.
## Metodología
```{r factores, include=FALSE}
tidy_presirvienta <- read.csv('data/tidy_presirvienta.csv')
#Convertir a formato de fecha
tidy_presirvienta$timestamp <- ymd_hms(tidy_presirvienta$timestamp)
# Convertir a factores
convertir_fact <- c('author', 'source', 'is_retweet', 'retweeted_user', 'is_quote_tweet', 'quoted_user', 'is_quote_withheld', 'is_reply', 'replied_user', 'is_withheld', 'Emotion')
tidy_presirvienta[convertir_fact] <- lapply(tidy_presirvienta[convertir_fact], as.factor)
# Filtrar las entradas entre el 1 de octubre y el 8 de octubre
# Definir el rango de fechas
start_date <- ymd("2024-10-01")
end_date <- ymd("2024-10-08")
# Filtrar las filas dentro del rango de fechas
tidy_presirvienta <- tidy_presirvienta %>%
filter(timestamp >= start_date & timestamp <= end_date)
```
La metodología que se siguió para esta investigación consistió en:
1. Recopilación de datos en la red social X, empleando una búsqueda entre los días 1 de octubre y 8 de octubre de todos los tuits en los que apareciera la palabra Presirvienta.
2. Para el registro de la busqueda y construcción de la base de datos se empleó primero el plugin de Firefox, [zeeschuimer](https://github.com/digitalmethodsinitiative/zeeschuimer) y posteriormente se importa la base de datos en [4Cat](https://4cat.nl/), se exportó la base de datos al formato estándar, csv (comma separated value).
3. Posteriormente, la base de datos se importó en el programa ["Orange Machine Learning"](https://orangedatamining.com/), en este se hizo un análisis de sentimientos y emociones empleando los algoritmos que el programa tiene para trabajar con datos en español. Una vez analizados los sentimientos y emociones, se agregan esas columnas a la base de datos anterior y se exporta una ves más en formato cvs.
4. En el programa Rstudio se carga la base de datos y ahí, empleando principalmente las librerías agrupadas en el ["tidyverse"](https://www.tidyverse.org/), además se sigue el proceso descrito en el libro [R for Data Science](https://r4ds.hadley.nz/): Importación; limpieza y acomodo; transformación; visualización: modelado; comunicación.

La exploración, la visualización, y la interpretación de los hallazgos de esta base de datos[^3], realizados todos empleando el lenguaje de programación R, se presentan a continuación:
[^3]: Los datos y la programación empleada, se encuentra en el repositorio: <https://github.com/juancbaena/presirvienta_EDA>
## Visualizaciones
A continuacion se presentan algunas graficas que permiten entender las publicaciones que emplearon el término presirvienta en la red social "X", del 1 de octubre al 8 de octubre (la primera semana de la Presidenta Claudia Sheinbaum).
### Resumen de los datos
```{r summary, include=FALSE}
datosdf <- tidy_presirvienta %>%
select(retweet_count, reply_count, like_count, quote_count, impression_count, Word.count, sentiment)
```
```{r tablas r, echo=FALSE}
datosdf %>%
gather(key = "Variable", value = "Valor") %>%
group_by(Variable) %>%
summarise(
N = n(),
Media = mean(Valor, na.rm = TRUE),
`Desv. Est.` = sd(Valor, na.rm = TRUE),
Mediana = median(Valor, na.rm = TRUE),
Mínimo = min(Valor, na.rm = TRUE),
Máximo = max(Valor, na.rm = TRUE)
) %>%
kable(
format = "markdown",
digits = 2,
caption = "Estadísticas descriptivas"
)
```
Esta tabla muestra un resumen estadístico de los datos recopilados que tienen una forma numérica, se puede observar que el total de publicaciones son 628, la publicación con más retuiteos tuvo se retuiteo alrededor de 5000 veces, el promedio de retuiteos es de 71. En el caso de respuestas el promedio es de 13 y la publicación que más tuvo, se respondió 1474 veces. En el caso de los likes, la publicación con más likes tuvo 16,168 y en promedio tuvieron 155 likes las publicaciones. En el caso de citaciones el promedio es de 2 y el máximo es de 290. Las impresiones tienen un promedio de 4,714 y la publicación que más impresiones tuvo fue 454,838. El análisis de sentimientos y el conteo de palabras se analizará más adelante.
### Histograma de publicaciones
```{r Hist dia, echo=FALSE}
tidy_presirvienta %>%
mutate(day = as.Date(timestamp)) %>% # Convertimos 'timestamp' a tipo Date
ggplot(aes(x = day)) +
geom_bar(fill = ft_cols$red , colour = ft_cols$slate) +
scale_x_date(date_labels = "%d/%m/%Y", date_breaks = "1 day") +
labs(x = "Día", y = "Cantidad", title = "Histograma de entradas por día", subtitle = "Publicaciones entre el 1 de octubre al 8 de octubre") +
theme_ft_rc()
```
En los 7 días que se analizan se puede observar que ni el primero de octubre, ni el 8 de octubre se registraron publicaciones, es importante observar que el día 3 de octubre es el día con más publicaciones, con más de 200 publicaciones, el día con menos fue el 5 de octubre, con alrededor de 70 publicaciones.
### Respuestas
```{r reply, echo=FALSE}
# Crear el dataframe con el conteo de "is_reply"
conteo_is_reply <- table(tidy_presirvienta$is_reply)
conteorep <- as.data.frame(conteo_is_reply)
# Renombrar las columnas para ggplot
colnames(conteorep) <- c("is_reply", "count")
# Crear el gráfico de pastel
ggplot(conteorep, aes(x = "", y = count, fill = is_reply)) +
geom_bar(stat = "identity", width = 1) +
coord_polar("y") +
labs(title = "Distribución de Tweets respuesta") +
theme_ft_rc(base_size = 15) +
scale_fill_manual(values = c("yes" = ft_cols$red , "no" = ft_cols$slate)) +
geom_text(aes(label = paste0(count, " (", round(count / sum(count) * 100), "%)")),
position = position_stack(vjust = 0.5)) # Añadir etiquetas con porcentajes
```
En la base de datos, 238 tuits son respuesta a otro tuit, esta cifra represena el 38 por ciento de las publicaciones, por tanto podemos afirmar que aproximadamente la mitad de las publicaciones o son una cita, o respuesta o un retuiteo, la otra mitad son tuits sin ningun tipo de estas interacciones.
## Caractéristicas numericas de las publicaciones
```{r nva_dataframe, echo=FALSE}
# Nueva dataframe para manejar menos datos
interacciones_presirvienta <- tidy_presirvienta %>%
select(id, author, source, hashtags, mentions , retweet_count, reply_count, like_count, quote_count, impression_count, is_reply, sentiment)
```
A continuación se presentan los resultados del análisis explorativo de todas las interacciones que se expresan de manera numérica.
### Conteo de menciones
```{r menciones, echo=FALSE}
interacciones_presirvienta %>%
select(mentions) %>%
drop_na() %>%
group_by(mentions) %>%
summarise(count = n()) %>%
arrange(desc(count)) %>%
filter(count > 3) %>%
ggplot(aes(x = reorder(mentions, -count), y = count)) +
geom_bar(stat = "identity", color = ft_cols$slate, fill = ft_cols$red) +
labs(title = "Frecuencia de menciones", x = "Menciones", y = "Conteo") +
theme_ft_rc() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1)
)
```
En el caso de los usuarios con más menciones está en primer lugar \@Claudiashein con 60 menciones y en segundo lugar \@Melissa_Bely con 19 menciones, se puede notar una diferencia importante entre las menciones.
### Conteo de autor con más respuestas
```{r Conteo respuestas, echo=FALSE}
tidy_presirvienta %>%
select(replied_user) %>%
drop_na() %>%
group_by(replied_user) %>%
summarise(count = n()) %>%
arrange(desc(count)) %>%
filter(count > 3) %>%
ggplot(aes(x = reorder(replied_user, -count), y = count)) +
geom_bar(stat = "identity", color = ft_cols$slate, fill = ft_cols$red) +
labs(title = "Conteo autor(a) más respuestas",
x = "Autores",
y = "Conteo de respuestas") +
theme_ft_rc() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
```
Los autores que más se les ha respondido en esta base de datos es \@Melissa_Bely con 20 tuits y \@Claudiashein con 15 tuits. En tercer lugar aparece \@lopezdoriga con 10 tuits. Cabe mencionar que los tuits originales a los cuales se les respondió, no aparecen, pues en ellos no se usa el término "Presirvienta", en cambio en los que contamos aquí, sí se emplea ese término.
### Conteo de sentimientos
```{r conteo sentimientos, echo=FALSE}
tidy_presirvienta%>%
ggplot(aes(x = sentiment, color = Emotion, fill = Emotion)) +
geom_histogram() +
stat_bin(binwidth = 10)+
theme_ft_rc() +
labs(x= 'Sentimientos', y= 'Conteo',
title = 'Histograma de sentimientos',
subtitle = 'Escala de -50 a +50') +
scale_color_ucscgb()
```
En el análisis de sentimientos, valorados por emociones de las publicaciones, se observa que el centro del histograma está en los sentimientos neutrales, sin embargo, existe una carga mayor de la distribución de valores hacia los sentimientos negativos, en el caso de las emociones, la alegría está por encima de todos los valores entre los valores neutrales, seguido de tristeza y sorpresa. el valor más bajo lo tiene la anticipación que no logra visualizar valores.
## Interacciones
En el caso de las interacciones que los usuarios tuvieron con las publicaciones de esta base de datos, es importante mencionar que vamos a analizar solo las interacciones *Likes* y *Retuits*.
### Likes
```{r Likes, echo=FALSE}
tidy_presirvienta %>%
filter(like_count<1000) %>%
ggplot(aes( x= Emotion, y= like_count, color = Emotion )) +
geom_jitter() +
labs(x = "Emoción", y = "Número de Likes",
title = 'Número de Likes por Emoción',
subtitle = 'Likes menores a 1000',
caption = 'Se filtraron para mejorar la visualización'
) +
coord_flip() +
theme_ft_rc() +
scale_color_ucscgb()+
theme(legend.position = "none")
```
En el caso de los Likes, en la gráfica anterior, es necesario señalar que se excluyeron los tuits con más de 1000 likes para poder visualizar qué emoción tiene mayor densidad. Como puede observarse, la sorpresa es la emoción con mayor número de tuits con likes, sin embargo los tuits con mayores likes, son aquellos que expresan tristeza.
### Retweets
```{r retweets, echo=FALSE}
tidy_presirvienta %>%
filter(retweet_count < 1000) %>%
ggplot(aes( x= Emotion, y= retweet_count, color = Emotion )) +
geom_jitter(width = .3, alpha = .5) +
labs(x = "Emoción", y = "Número de Likes",
title = 'Número de Retuits por Emoción',
subtitle = 'Retuits menores a 1000',
caption = 'Se filtraron para mejorar la visualización'
) +
coord_flip() +
theme_ft_rc() +
scale_color_ucscgb()+
theme(legend.position = "none")
```
En el caso de las interacciones de los usuarios retuiteando publicaciones, la emoción con mayor densidad sigue siendo la sorpresa, seguida de la alegría, sin embargo, la emoción que tiene publicación con mayor número de retuiteos, es la confianza.
### Respuestas
```{r respuestas, echo=FALSE}
tidy_presirvienta %>%
filter(reply_count <200) %>%
ggplot(aes( x= Emotion, y= reply_count, color = Emotion )) +
geom_jitter(width = .3, alpha = .5) +
labs(x = "Emoción", y = "Número de Respuestas",
title = 'Número de Respuestas por Emoción',
subtitle = 'Respuestas menores a 200',
caption = 'Se filtraron para mejorar la visualización'
) +
coord_flip() +
theme_ft_rc() +
scale_color_ucscgb()+
theme(legend.position = "none")
```
En el caso de las publicaciones que han sido respondidas por otros usuarios, la emoción con mayor densidad es la sorpresa, seguido de la alegría. Sin embargo, la emoción con tuits con mayor número de respuesta es la confianza.
### Plots sobre interacciones
A continuación se visualizan las relaciones entre las interacciones, tomando como base el número de likes para entender el comportamiento y relaciones entre estas variables de interacción.
### Likes vs. Respuestas
```{r likevsrespuestas, echo=FALSE}
interacciones_presirvienta %>%
filter(like_count>50, reply_count > 50) %>%
ggplot(aes(x = like_count, y= reply_count)) +
geom_smooth(method = loess, color = ft_cols$yellow, fill = ft_cols$slate) +
geom_point(color = ft_cols$red) +
theme_ft_rc() +
labs(
x = 'Número de likes',
y = 'Número de respuestas',
title = 'Likes vs. Respuestas',
subtitle = 'Mayores a 50'
)
```
En el caso del número de likes y el número de respuestas, los tuits que tienen menos de 7500 likes y menos de 1000 respuestas, tienen una relación pues aumentan acorde a la misma tendencia, sin embargo en el caso de los tuis con mayor número de likes, no siguen una dirección lineal, sino que van decreciendo, de tal manera que el último tuit, con más de 15,000 likes, sus número de respuestas no aumenta con la misma tendencia lineal que los tuits con menos likes.
### Likes vs. retuits
```{r likevsretuit, echo=FALSE}
interacciones_presirvienta %>%
filter(like_count> 100, retweet_count > 100) %>%
ggplot(aes(x = like_count, y= retweet_count)) +
geom_smooth(method = loess, color = ft_cols$yellow, fill = ft_cols$slate) +
geom_point(color = ft_cols$red) +
theme_ft_rc() +
labs(
x = 'Número de likes',
y = 'Número de retuits',
title = 'Likes vs. Retuits',
subtitle = 'Mayores a 100'
)
```
La relación entre el número de likes y el número de retuits no sigue una relación lineal, los tuits con menos de 5,000 likes siguen una tendencia lineal con respecto al número de retuits, sin embargo al pasar los 5,000 likes, la tendencia cambia para describir una curva descendente.
### Likes vs. Sentimientos
```{r likevssentim, echo=FALSE}
library(ggsci)
tidy_presirvienta %>%
filter(like_count<200) %>%
ggplot(aes(x = like_count, y= sentiment, color = Emotion)) +
geom_point() +
scale_color_ucscgb() +
theme_ft_rc() +
scale_y_continuous(labels = comma_format(big.mark = ".", decimal.mark = ","))+
facet_wrap( ~ is_reply)+
labs(
x = 'Número de likes',
y = 'Valores de sentimientos',
title = 'Likes vs. Sentimientos',
subtitle = 'Filtrado por respuesta'
)
```
En la gráfica anterior se puede observar que el número de likes relacionado con la valoración de los sentimientos, los tuits con mayor densidad son aquellos que están en los valores neutrales, sin embargo tanto en los tuits que son respuesta y los que no son, la gráfica tienen una tendencia hacia los valores negativos, por tanto, existe mayor densidad hacia los valores negativos.
## Exploración sobre los textos de las publicaciones
```{r librerias2, include=FALSE}
library(stringr)
library(tidytext)
library(tm)
library(wordcloud2)
```
```{r dataframe, include=FALSE, echo=FALSE}
tidy_presirvienta1 <- read.csv('data/tidy_presirvienta.csv')
# Se escogen solo las columnas que van a servirnos
tidy_presirvienta1 <- tidy_presirvienta1 %>%
select(id, timestamp, author, body, Emotion)
# Convertir a formato de fecha
tidy_presirvienta1$timestamp <- ymd_hms(tidy_presirvienta1$timestamp)
# Filtrar las entradas entre el 1 de octubre y el 8 de octubre
# Definir el rango de fechas
start_date <- ymd("2024-10-01")
end_date <- ymd("2024-10-08")
# Filtrar las filas dentro del rango de fechas
tidy_presirvienta1 <- tidy_presirvienta1 %>%
filter(timestamp >= start_date & timestamp <= end_date)
```
```{r limpieza, include=FALSE, echo=FALSE}
limp_presirvienta <- tidy_presirvienta1 %>%
select(timestamp, author, body, Emotion) %>%
mutate(body = str_replace_all(body, '(http|https)[^([:blank:]|\\"|<|&|#\n\r)]+', "")) %>%
mutate(body = str_replace_all(body, "@\\S+", "")) %>%
unnest_tokens(word, body) %>%
anti_join(tibble(word = tm::stopwords("es")))
```
A continuación se presenta el trabajo de análisis de la columna del contenido textual de la base de datos, se presentan diferentes gráficos para entender mejor el contenido de los tuits de la base de datos.
### Bigramas
```{r bigramas, include=FALSE, echo=FALSE}
bigram_presirvienta <- tidy_presirvienta1 %>%
select(timestamp, author, body, Emotion) %>%
mutate(body = str_replace_all(body, '(http|https)[^([:blank:]|\\"|<|&|#\n\r)]+', "")) %>%
mutate(body = str_replace_all(body, "@\\S+", "")) %>%
unnest_tokens(bigram, body, token = "ngrams", n = 2) %>%
separate(bigram, c("word1", "word2"), sep = " ") %>%
anti_join(tibble(word1 = tm::stopwords("es"))) %>%
anti_join(tibble(word2 = tm::stopwords("es"))) %>%
unite(bigram, word1, word2, sep = " ")
```
```{r conteosbigramas, include=FALSE, echo=FALSE}
#conteo de ocurrencias por palabras gral.
conteobigramas_presirvienta <- bigram_presirvienta %>%
count(bigram, sort = TRUE) %>%
filter(!bigram == 'NA NA') %>%
filter(!bigram == 'presirvienta presirvienta')
```
El primer trabajo de análisis es contabilizar lo que se ha denominado bigramas, se contabiliza la combinación de 2 palabras que más se repiten, con esto se busca entender qué palabras son las más usadas, pero también combinación con otra palabras para lograr tener un mejor contexto del uso de las palabras y lograr extraer significados.
### Gráficas de los bigramas
```{r graficas_bigramas, echo=FALSE}
conteobigramas_presirvienta %>%
filter(n > 6) %>%
mutate(bigram = reorder(bigram, n)) %>%
ggplot(aes(n, bigram)) +
geom_col(colour = ft_cols$slate, fill = ft_cols$red) +
labs(y = NULL, x = 'conteo',
title = 'Bigramas con ocurrencia mayor a 6')+
theme(legend.position = "none")+
theme_ft_rc()
```
En este gráfico es posible observar que los bigramas más empleados son, en primer lugar, el nombre de la presidenta: Claudia Sheinbaum. Sin embargo en segundo lugar se emplea presirvienta espuria y en tercer lugar, digan presirvienta. Es importante señalar que aparece el nombre del cómico mexicano: Rafael Inclan en cuarto lugar.
```{r librerías, include=FALSE}
library(topicmodels)
library(tm)
library(SnowballC)
```
## Modelado de tópicos #Presirvienta
El modelado de tópicos es un proceso que permite identificar patrones de tópicos en un conjunto de textos, en esta ocasión se realizó este modelado a partir del contenido de los tuits recopilados en la búsqueda con el termino "Presirvienta"
```{r cargardf, include=FALSE}
tidy_presirvienta1 <- read.csv('data/tidy_presirvienta.csv')
# Se escogen solo las columnas que van a servirnos
tidy_presirvienta1 <- tidy_presirvienta1 %>%
select(id, timestamp, author, body, Emotion)
```
```{r limpieza2, include=FALSE, echo=FALSE}
document <- Corpus(VectorSource(tidy_presirvienta1$body))
# limpieza del texto
document <- tm_map(document, content_transformer(tolower))
document <- tm_map(document, removeNumbers)
document <- tm_map(document, removePunctuation, preserve_intra_word_dashes = TRUE)
document <- tm_map(document, removeWords, c(stopwords("es"), "presirvienta"))
document <- tm_map(document, stripWhitespace)
removeURLs <- function(x) {
gsub("http[[:alnum:][:punct:]]*", "", x)
}
# Función para eliminar emojis
removeEmojis <- function(x) {
gsub("[\U0001F600-\U0001F64F]|[\U0001F300-\U0001F5FF]|[\U0001F680-\U0001F6FF]|[\U0001F700-\U0001F77F]|[\U0001F780-\U0001F7FF]|[\U0001F800-\U0001F8FF]|[\U0001F900-\U0001F9FF]|[\U0001FA00-\U0001FA6F]|[\U0001FA70-\U0001FAFF]|[\U00002702-\U000027B0]|[\U000024C2-\U0001F251]", "", x, perl = TRUE)
}
# Aplicar las funciones al corpus
document <- tm_map(document, content_transformer(removeURLs))
document <- tm_map(document, content_transformer(removeEmojis))
```
```{r preparación, include=FALSE, echo=FALSE}
# Crear la Document-Term Matrix
dtm <- DocumentTermMatrix(document)
# Eliminar términos poco frecuentes
dtm <- removeSparseTerms(dtm, 0.99)
row_sums <- rowSums(as.matrix(dtm))
empty_docs <- which(row_sums == 0)
#Eliminar documentos vacíos
dtm <- dtm[row_sums > 0, ]
# Establecer el número de tópicos
num_topics <- 10
# Ajustar el modelo LDA
lda_model <- LDA(dtm, k = num_topics, control = list(seed = 1234))
# Ver los términos principales de cada tópico
terms(lda_model, 10) # 10 términos principales por tópico
# Ver la distribución de tópicos en los documentos
topics(lda_model)
```
```{r extraer, echo=FALSE}
# Extraer los términos principales de cada tópico junto con sus valores beta
top_terms <- terms(lda_model, 10)
beta_matrix <- posterior(lda_model)$terms
# Crear una lista para almacenar los datos
top_terms_list <- list()
# Recorrer cada tópico
for (topic in 1:num_topics) {
terms_beta <- beta_matrix[topic, top_terms[, topic]]
top_terms_list[[topic]] <- data.frame(
topic = rep(topic, length(terms_beta)),
term = names(terms_beta),
beta = terms_beta
)
}
# Combinar todos los dataframes en uno solo
top_terms_df <- do.call(rbind, top_terms_list)
# Crear la gráfica
ggplot(top_terms_df, aes(x = reorder(term, -beta), y = beta, fill = factor(topic))) +
geom_bar(stat = "identity", show.legend = FALSE) +
facet_wrap(~ topic, scales = "free") +
coord_flip() +
labs(title = "Top 10 Palabras por Tópico", x = "Palabra", y = "Valor Beta") +
theme_ft_rc() +
scale_color_ucscgb()
```
En estos gráficos se infiere que el primer núcleo de significados hace referencia a la presidenta y cómo la nombran "presirvienta", además la palabra "amo" aparece completando el significado del tópico, indicando servilismo por parte de la Presidenta.
En el segundo núcleo aparece el nombre de Rafael Inclán y la palabra ama de casa, haciendo referencia a las declaraciones del cómico. En el tercer núcleo, al igual que el quinto, harían referencia a la idea que el sexenio de la Presidenta sería igual al sexenio pasado, una "calca" del anterior.
En el cuarto núcleo se ubican aquellos contenidos que hablarían de una crítica hacia el expresidente y hacia la Presidenta, sin embargo aparece también el adjetivo "chairos" ubicandolo en torno a está crítica.
En el sexto y séptimo núcleos, aparece el adjetivo "espúria" también hace referencia a la acción de la Presidenta de besar la mano de el político Manuel Velazco. En el caso de los núcleos 8, 9 y 10 no se puede apreciar un significado relevante.
## Conclusiones
El análisis exploratorio de datos realizado sobre las publicaciones que contienen el término "Presirvienta" en la red social "X", durante la primera semana de la presidencia de Claudia Sheinbaum, revela patrones significativos tanto en el comportamiento de los usuarios como en el contenido de sus mensajes.
## Hallazgos Principales
1. Métricas de comportamiento:
- El día con más publicaciones fue el 3 de octubre
- Del total de publicaciones (628), el 38% son respuestas a otros tuits, mientras que el 62% son publicaciones originales
- Se observó una relación no lineal entre likes, retuits y respuestas: en valores bajos el crecimiento es proporcional, pero esta proporcionalidad se pierde en valores más altos
2. Análisis de Contenido:
- Las cuentas más mencionadas fueron @Claudiashein y @Melissa_Bely
- Los bigramas más frecuentes identificados fueron "Claudia Sheinbaum", "presirvienta espuria" y "digan presirvienta", seguidos por menciones a Rafael Inclán
3. Análisis de Sentimientos y Tópicos:
- El análisis de sentimientos reveló una predominancia de expresiones negativas
- Se identificaron cinco núcleos temáticos principales:
- Primer tópico: Referencias al supuesto servilismo de la presidenta
- Segundo tópico: Declaraciones de Rafael Inclán
- Tercer y quinto tópico: Esta administración será una copia a la anterior
- Cuarto tópico: Críticas despectivas hacia la presidenta
- Último tópico: Cuestionamientos sobre legitimidad y críticas a gestos específicos (besar la mano de un político)
Los hallazgos sugieren que las reacciones negativas hacia la presidenta Sheinbaum están fuertemente mediadas por sesgos de género y clase social. El uso del término "Presirvienta" opera en dos niveles discriminatorios: primero, como una expresión de misoginia al cuestionar la capacidad de liderazgo por razón de género; segundo, como manifestación de clasismo al pretender utilizar las labores domésticas como forma de descalificación.
La respuesta de la presidenta, enfatizando la dignidad de todos los trabajos, pone en evidencia una problemática más amplia: la persistencia en México de estructuras sociales que discriminan tanto por género como por condición socioeconómica.
Es importante reconocer las limitaciones metodológicas de este estudio:
- El análisis se centró en patrones generales sin profundizar en el contenido específico de cada publicación
- Los métodos empleados revelan tendencias en el uso de palabras pero no capturan completamente los significados subyacentes
- El período de análisis fue relativamente corto
El monitoreo y análisis de los discursos en redes sociales se presenta como una tarea cada vez más urgente, especialmente ante la creciente agresividad en los espacios digitales. Si bien el debate público es fundamental para la democracia, es igualmente importante identificar y señalar cuando los discursos perpetúan discriminaciones históricas. Esto es especialmente relevante cuando afectan a grupos que han enfrentado marginación sistemática.