library(rwhatsapp)
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.2 ✓ purrr 0.3.4
## ✓ tibble 3.0.3 ✓ dplyr 1.0.1
## ✓ tidyr 1.1.1 ✓ stringr 1.4.0
## ✓ readr 1.3.1 ✓ forcats 0.5.0
## ── Conflicts ────────────────────────────────────────────── tidyverse_conflicts() ──
## x lubridate::as.difftime() masks base::as.difftime()
## x lubridate::date() masks base::date()
## x dplyr::filter() masks stats::filter()
## x lubridate::intersect() masks base::intersect()
## x dplyr::lag() masks stats::lag()
## x lubridate::setdiff() masks base::setdiff()
## x lubridate::union() masks base::union()
library(tidytext)
library(kableExtra)
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
library(RColorBrewer)
library(knitr)
library(ggimage)
library(stopwords)
miChat <- rwa_read("Chat de WhatsApp con Marce.txt")
miChat <- miChat %>%
mutate(day = date(time)) %>%
mutate(
# SEGMENTACIÓN POR SEMESTRE
semestre = case_when(
day >= ymd(20190701) & day <= ymd(20191231) ~ "Segundo de 2019",
day >= ymd(20200101) & day <= ymd(20200630) ~ "Primero de 2020",
day >= ymd(20200701) & day <= ymd(20201231) ~ "Segundo de 2020",
T ~ "Fuera de rango")
) %>%
mutate( semestre = factor(semestre) ) %>%
filter(!is.na(author))
paleta.semestres <- brewer.pal(8,"Set1")[c(7,5,1,3,4,2,6,8)]
miChat %>%
group_by(semestre) %>%
count(day) %>%
ggplot(aes(x = day, y = n, fill=semestre)) +
geom_bar(stat = "identity") +
scale_fill_manual(values=paleta.semestres) +
ylab("Número de mensajes") + xlab("Fecha") +
ggtitle("Mensajes por día", "Frecuencia por semestre del año") +
theme_minimal() +
theme( legend.title = element_blank(),
legend.position = "right")
#El año pasado había una mayor frecuencia de mensajes que este año, el segundo semestre del año presenta la menor frecuencia
miChat %>%
mutate( wday.num = wday(day),
wday.name = weekdays(day)) %>%
group_by(semestre, wday.num, wday.name) %>%
count() %>%
ggplot(aes(x = reorder(wday.name, -wday.num), y = n, fill=semestre)) +
geom_bar(stat = "identity") +
scale_fill_manual(values=paleta.semestres) +
ylab("") + xlab("") +
coord_flip() +
ggtitle("Número de mensajes por día de la semana", "Frecuencia por semestre del año") +
theme_minimal() +
theme( legend.title = element_blank(),
legend.position = "right")
#Los días con mayor frecuencia son los lunes y los jueves
diasemana <- c("domingo","lunes","martes","miércoles","jueves","viernes","sábado","domingo")
names(diasemana) <- 1:7# MENSAJES POR HORA DEL DÍA
miChat %>%
mutate( hour = hour(time),
wday.num = wday(day),
wday.name = weekdays(day)) %>%
count(semestre, wday.num, wday.name, hour) %>%
ggplot(aes(x = hour, y = n, fill=semestre)) +
geom_bar(stat = "identity") +
scale_fill_manual(values=paleta.semestres) +
ylab("Número de mensajes") + xlab("Horario") +
ggtitle("Número de mensajes por hora del día", "Frecuencia según semestre del año") +
facet_wrap(~wday.num, ncol=7, labeller = labeller(wday.num=diasemana))+
theme_minimal() +
coord_flip() +
theme( legend.title = element_blank(),
legend.position = "right",
panel.spacing.x=unit(0.0, "lines"))
miChat <- miChat %>%
mutate(author = case_when(author == "Xiomy Díaz" ~ "Xiomy", author != "Xiomy Díaz" ~ "Marce"))
glimpse(miChat)
## Rows: 35,459
## Columns: 9
## $ time <dttm> 2019-06-06 10:19:23, 2019-06-06 10:32:23, 2019-06-06 10:4…
## $ author <chr> "Marce", "Xiomy", "Marce", "Marce", "Xiomy", "Marce", "Xio…
## $ text <chr> "Hola Xiomy... La family??", "Hola Si, ☺", "\U0001f44f\U00…
## $ source <chr> "Chat de WhatsApp con Marce.txt", "Chat de WhatsApp con Ma…
## $ id <int> 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ emoji <list> [NULL, "☺", <"\U0001f44f", "\U0001f3fd", "\U0001f44f", "\…
## $ emoji_name <list> [NULL, "smiling face", <"clapping hands", "medium skin to…
## $ day <date> 2019-06-06, 2019-06-06, 2019-06-06, 2019-06-06, 2019-06-0…
## $ semestre <fct> Fuera de rango, Fuera de rango, Fuera de rango, Fuera de r…
miChat %>%
mutate(day = date(time)) %>%
group_by(semestre) %>%
count(author) %>%
ggplot(aes(x = reorder(author, n), y = n, fill=semestre)) +
geom_bar(stat = "identity") +
scale_fill_manual(values=paleta.semestres) +
ylab("Número total de mensajes") + xlab("Usuario") +
coord_flip() +
ggtitle("Número total de mensajes por usuario.", "¿Quién es más comunicativo? Frecuencia por estación del año") +
theme_minimal() +
theme( legend.title = element_blank(),
legend.position = "right")
#Marce tiene mayor frecuencia de mensajes, sin embargo en el segundo semestre del año 2020 Xiomy tiene mayor número de mensajes
plotEmojis <- miChat %>%
unnest(emoji, emoji_name) %>%
mutate( emoji = str_sub(emoji, end = 1)) %>%
mutate( emoji_name = str_remove(emoji_name, ":.*")) %>%
count(emoji, emoji_name) %>%
# PLOT TOP 30 EMOJIS
top_n(30, n) %>%
arrange(desc(n)) %>% # CREA UNA URL DE IMAGEN CON EL UNICODE DE EMOJI
mutate( emoji_url = map_chr(emoji,
~paste0( "https://abs.twimg.com/emoji/v2/72x72/", as.hexmode(utf8ToInt(.x)),".png"))
)
## Warning: unnest() has a new interface. See ?unnest for details.
## Try `df %>% unnest(c(emoji, emoji_name))`, with `mutate()` if needed
plotEmojis %>%
ggplot(aes(x=reorder(emoji_name, n), y=n)) +
geom_col(aes(fill=n), show.legend = FALSE, width = .2) +
geom_point(aes(color=n), show.legend = FALSE, size = 3) +
geom_image(aes(image=emoji_url), size=.045) +
scale_fill_gradient(low="#2b83ba",high="#d7191c") +
scale_color_gradient(low="#2b83ba",high="#d7191c") +
ylab("Número de veces que el emoji fue usado") +
xlab("Emoji y significado") +
ggtitle("Emojis más utilizados de manera general", "Emojis más usados por todos") +
coord_flip() +
theme_minimal() +
theme()
plotEmojis <- miChat %>%
unnest(emoji, emoji_name) %>%
mutate( emoji = str_sub(emoji, end = 1)) %>% #
count(author, emoji, emoji_name, sort = TRUE) %>%# PLOT DEL TOP 8 EMOJIS POR USUARIO
group_by(author) %>%
top_n(n = 8, n) %>%
slice(1:8) %>%
# CREA UNA URL DE IMAGEN CON EL UNICODE DE EMOJI
mutate( emoji_url = map_chr(emoji,
~paste0("https://abs.twimg.com/emoji/v2/72x72/",as.hexmode(utf8ToInt(.x)),".png")) )
## Warning: unnest() has a new interface. See ?unnest for details.
## Try `df %>% unnest(c(emoji, emoji_name))`, with `mutate()` if needed
plotEmojis %>%
ggplot(aes(x = reorder(emoji, -n), y = n)) +
geom_col(aes(fill = author, group=author), show.legend = FALSE, width = .20) +# USAR PARA HACER FETCH DE UNA IMAGEN PNG DE EMOJI https://abs.twimg.com
geom_image(aes(image=emoji_url), size=.13) +
ylab("Número de veces que se usó el emoji") +
xlab("Emoji") +
facet_wrap(~author, ncol = 5, scales = "free") +
ggtitle("Emojis más usados en la conversación, por usuario") +
theme_minimal() +
theme(axis.text.x = element_blank())
#El emoji más usado por Marce es Clapping Hands: Medium-Light Skin Tone, en la codificación sales solo como Medium-Light Skin Tone
remover_palabras <- c(stopwords(language = "pt"), "m", "the", "11", "1", "p", "20", "10", "05", "19", "5", "2", "to", "6", "c", "3", "7", "4", "00", "12", "18", "17", "03", "04", "f", "8", "x", "09", "50", "multimedia", "y", "la", "el", "en", "es", "si", "lo", "ya", "pero", "esa", "los", "yo", "mi", "un", "con", "las", "omitido", "más", "eso", "al", "una", "del", "qué", "todo", "así", "le", "su", "va", "porque", "todos", "hay", "les", "pue", "ese", "son", "está", "pues", "ahí", "sí", "ver", "estás", "algo", "vas", "ir", "voy", "creo", "fue", "solo", "ni", "sólo", "nada", "aqui", "q", "tú","muy", "ti" , "pq", "tus")
miChat %>%
unnest_tokens(input = text, output = word) %>%
filter(!word %in% remover_palabras) %>%
count(word) %>% # PLOT DEL TOP 30 DE PALABRAS MÁS USADAS EN CONVERSACIÓN
top_n(30,n) %>%
arrange(desc(n)) %>%
ggplot(aes(x=reorder(word,n), y=n, fill=n, color=n)) +
geom_col(show.legend = FALSE, width = .1) +
geom_point(show.legend = FALSE, size = 3) +
scale_fill_gradient(low="#2b83ba",high="#d7191c") +
scale_color_gradient(low="#2b83ba",high="#d7191c") +
ggtitle("Palabras más usadas en la conversación de manera general") +
xlab("Palabras") +
ylab("Número de veces que se usó la palabra") +
coord_flip() +
theme_minimal()
miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras) %>%
count(author, word, sort = TRUE) %>%
# TOP 20 PALABRAS MÁS USADAS POR USUARIO
group_by(author) %>%
top_n(n = 20, n) %>%
slice(1:20) %>%
ungroup() %>%
arrange(author, desc(n)) %>%
mutate(order=row_number()) %>%
ggplot(aes(x = reorder(word, n), y = n, fill = author, color = author)) +
geom_col(show.legend = FALSE, width = .1) +
geom_point(show.legend = FALSE, size = 3) +
xlab("Palabras") +
ylab("Número de veces que se usó la palabra") +
coord_flip() +
facet_wrap(~author, ncol = 3, scales = "free") +
ggtitle("Palabras más usadas por usuario en la conversación") +
theme_minimal()
miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras) %>%
group_by(author) %>%
summarise(lex_diversity = n_distinct(word)) %>%
arrange(desc(lex_diversity)) %>%
ggplot(aes(x = reorder(author, lex_diversity),
y = lex_diversity,
fill = author)) +
geom_col(show.legend = FALSE) +
scale_y_continuous(expand = (mult = c(0, 0, 0, 500))) +
geom_text(aes(label = scales::comma(lex_diversity)), hjust = -0.1) +
ylab("Diversidad léxica") +
xlab("Usuario") +
ggtitle("Diversidad de léxico en la conversación") +
coord_flip()
## `summarise()` ungrouping output (override with `.groups` argument)
palabras_unicas_ella <- miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras, author != "Marce") %>%
count(word, sort = TRUE)
miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras, author == "Marce") %>%
count(word, sort = TRUE) %>%
filter(!word %in% palabras_unicas_ella$word) %>%
# SELECCIONAR SÓLO PALABRAS QUE NADIE MÁS USA
top_n(n = 15, n) %>%
ggplot(aes(x = reorder(word, n), y = n)) +
geom_col(show.legend = FALSE) +
ylab("Número de veces que se usó la palabra") + xlab("Palabras") +
coord_flip() +
ggtitle("Top de palabras únicas usadas por Marce")
palabras_unicas_ella <- miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras, author != "Xiomy") %>%
count(word, sort = TRUE)
miChat %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% remover_palabras, author == "Xiomy") %>%
count(word, sort = TRUE) %>%
filter(!word %in% palabras_unicas_ella$word) %>%
# SELECCIONAR SÓLO PALABRAS QUE NADIE MÁS USA
top_n(n = 15, n) %>%
ggplot(aes(x = reorder(word, n), y = n)) +
geom_col(show.legend = FALSE) +
ylab("Número de veces que se usó la palabra") + xlab("Palabras") +
coord_flip() +
ggtitle("Top de palabras únicas usadas por Xiomy")
library(rvest)
## Loading required package: xml2
##
## Attaching package: 'rvest'
## The following object is masked from 'package:purrr':
##
## pluck
## The following object is masked from 'package:readr':
##
## guess_encoding
url_base <- "http://kt.ijs.si/data/Emoji_sentiment_ranking/index.html"
doc <- read_html(url_base)# BUSCAR TABLA DE EMOJI Y PROCESO
tabla_emojis <- doc %>%
html_node("#myTable") %>%
html_table() %>%
as_tibble()
library(purrr)
sentimiento_emoji <- tabla_emojis %>%
select(1,6:9) %>%
purrr::set_names("char", "negativo","neutral","positivo","sent.score")
emoji_chat <- miChat %>%
unnest(c(emoji, emoji_name)) %>%
mutate( emoji = str_sub(emoji, end = 1)) %>%
inner_join(sentimiento_emoji, by=c("emoji"="char"))
#score
emoji_chat %>%
select(-source, -day, -semestre) %>%
slice(c(1,n())) %>%
kable() %>%
kable_styling(font_size = 10)
| time | author | text | id | emoji | emoji_name | negativo | neutral | positivo | sent.score |
|---|---|---|---|---|---|---|---|---|---|
| 2019-06-06 10:32:23 | Xiomy | Hola Si, ☺ | 3 | ☺ | smiling face | 0.062 | 0.218 | 0.720 | 0.657 |
| 2020-10-15 02:32:23 | Marce | Y todo se ve delicioso aunque un poco 🙈🙈 | 35383 | 🙈 | see-no-evil monkey | 0.164 | 0.241 | 0.596 | 0.432 |
emoji_sentimiento_usuarios <- emoji_chat %>%
group_by(author) %>%
summarise(
positivo=mean(positivo),
negativo=mean(negativo),
neutral=mean(neutral),
balance=mean(sent.score), .groups = 'drop'
) %>%
arrange(desc(balance))
emoji_sentimiento_usuarios %>%
mutate( negativo = -negativo,
neutral.positivo = neutral/2,
neutral.negativo = -neutral/2) %>%
select(-neutral) %>%
gather("sentiment","mean", -author, -balance) %>%
mutate(sentiment = factor(sentiment, levels = c("negativo", "neutral.negativo", "positivo", "neutral.positivo"), ordered = T)) %>%
ggplot(aes(x=reorder(author,balance), y=mean, fill=sentiment)) +
geom_bar(position="stack", stat="identity", show.legend = F, width = .5) +
scale_fill_manual(values = brewer.pal(4,"RdYlGn")[c(1,2,4,2)]) +
ylab(" - Negativo / Neutral / Positivo +") + xlab("Usuario") +
ggtitle("Análisis de sentimientos por usuario","Basado en el puntaje promedio de sentimientos por emojis") +
coord_flip() +
theme_minimal()
#De acuerdo al score Marce tiene un mayor promedio de sentimientos negativos basado en el puntaje promedio de sentimientos por emojis