Analisando conversas de Whatsapp no R: conhecendo o poder da comunicação digital

Dalton Costa
Datapsico
Published in
10 min readJun 12, 2021

Dizem por aí que a comunicação é o segredo para se manter qualquer relacionamento. Particularmente, eu concordo com essa afirmação. Sem comunicação saudável, qualquer relacionamento está praticamente morto. Estamos vivendo um momento em que os relacionamentos e a comunicação passam pelos dispositivos eletrônicos, como o WhatsApp. As primeiras mensagens, momentos marcantes, discussões e diversões estão todos registrados. Que tal visitar essa história por meio da análise de dados? Afinal, estamos no dia mais amoroso do ano, o dia dos namorados ❤

Esse artigo é dedicado a todas as pessoas que possuem alguém especial e quer conhecer um pouco mais sobre a comunicação nessa relação.

Nesse artigo, analisaremos as mensagens do WhatsApp e você pode utilizar os seus próprios dados para testar. Você pode analisar conversas com o seu(ua) namorado(a), pais ou amigos. Usaremos a linguagem R nessa análise e diversos pacotes para deixar nossos gráficos incríveis.

O código completo desse artigo pode ser consultado nesse link.

Faça sua análise utilizando o Shiny

Se você está muito ansioso e não quer implementar o código agora, você pode usar o Shiny app desenvolvido.

Para acessar o shiny acesse o link: https://daltonbc.shinyapps.io/whatsapp/

Você precisa inserir seus de mensagens do whatsapp* e você pode consegui-los seguindo os passos abaixo.

* O Shiny app foi desenvolvido para ser apenas um visualizador de dados. No momento que você fecha a página ou recarrega a página os seus dados são apagados. Se você não se sente confortável em utilizar o app, você pode executar o código descrito abaixo para analisar localmente no seu computador.

Baixando conversas do WhatsApp

Para baixar a conversa basta clicar nos três pontos no canto superior direito, em seguida clique em “mais” e “exportar conversa”. Escolha um aplicativo que te permita ter acesso ao arquivo gerado (dica: utilize o e-mail ou até mesmo o WhatsApp). Será gerado um arquivo do tipo .txt e é com ele que vamos trabalhar.

Com os dados em mãos você pode inseri-lo no aplicativo. No canto superior esquerdo clique no campo escrito “selecione um arquivo”, então irá abrir uma janela para você selecionar o seu arquivo com final .txt.

Se você prefere executar o código na sua máquina, vou te ensinar a partir de agora!

Analisando os dados

Com os dados em mãos, você pode iniciar o processo de análise!

Você irá precisar dos seguintes pacotes:

library("rwhatsapp")
library("dplyr")
library("ggplot2")
library("ggimage")
library("plotly")
library("wordcloud")
library("reshape2")
library("tm")
library("tidytext")
library("tidyr")
library("lubridate")
library("ggthemes")
library("hms")
#configure e certifique-se que o seu sistema R está em pt-br
#esse procedimento é importante para as datasSys.setlocale("LC_TIME", "Portuguese")
Sys.getlocale("LC_TIME")

Carregando os dados

O primeiro passo é carregar os dados no R e realizar alguns ajustes nos dados. A boa notícia é que existe um pacote que processa de forma automática dados vindos do WhatsApp. O nome do pacote é “rwhatsapp”. Portanto, o primeiro passo é carregar os dados (arquivo .txt) com a função “rwa_read()” do pacote “rwhatsapp”. Veja no código abaixo as demais configurações.

chat <- rwa_read('chat.txt') %>% 
filter(!is.na(author)) %>%
filter(text != '<Arquivo de mídia oculto>')%>%
mutate(
date = ymd(date(time)),
hours = as_hms(time),
text = gsub('[[:punct:] ]+',' ',text ),
text = iconv(text, from = 'UTF-8', to = 'ASCII//TRANSLIT'),
text = lapply(text, tolower),
text = gsub('[[:punct:] ]+',' ',text ),
text = trimws(gsub("\\w*[0-9]+\\w*\\s*", "", text)),
text = gsub('([[:alpha:]])\\1+', '\\1', text )
)

Nessa etapa, primeiro carregamos os dados e em seguida filtramos/removemos os casos que não possuem autor e que tivessem a mensagem ‘<Arquivo de mídia oculto>’. Essa mensagem pode variar de acordo com o seu aparelho e linguagem, alguns podem ser a mensagem “image omitted”. No restante, configuramos as variáveis de “data” e “hora”. E por fim, na variável “text”, passamos todas as palavras para minúscula, removemos acentos, pontuações, números e palavras com sequência de letras repetidas, como “kkkkkkkk”.

Dados descritivos

Você pode verificar informações exatas com base nas datas das conversas, como: primeiro e último dia, dias corridos e ativos e o número de semanas.

#Primeiro dia
min(chat$date)
#Último dia
max(chat$date)
#Dias ativos
length(unique(chat$date))
#Diferença do último para o primeiro dia
max(chat$date) - min(chat$date)
#Número de semanas
as.numeric(min(chat$date) %--% max(chat$date), "weeks")

Número de mensagens ao longo do tempo

O nosso primeiro gráfico irá apresentar o número de mensagens trocadas ao longo do tempo. Para isso, vamos contar quantas mensagens foram trocadas em cada dia. Observe que foi criado um gráfico do tipo série temporal e para facilitar sua visualização, atribuímos o gráfico criado ao pacote “plotly” utilizando a função “ggplotly()”. Essa função permite que você possa interagir com o gráfico.

Note, também, que foi incluído no gráfico uma linha azul, que representa a média smoothed average (média móvel). Essa medida auxilia o leitor no processo de leitura de gráficos e evita overplotting (quando os dados de um gráfico se sobrepõem, tornando difícil ver pontos de dados individuais).

fig <-chat %>%
mutate(day = date) %>%
count(day) %>%
ggplot(aes(x = day, y = n)) +
geom_line(aes(x = day, y = n), color="#F8766D") +
geom_smooth(aes(x = day, y = n, col = "Average"), se = FALSE, color = "#00BFC4") +
ylab("Quantidade de Mensagens") + xlab("Data da Conversa") +
ggtitle("Número de mensagens do Whatsapp enviadas por dia")+
theme_hc()
ggplotly(fig)

Nesse gráfico podemos observar que, ao longo do tempo, a conversa começa a apresentar certa estabilidade na frequência de mensagens. É possível observar no gráfico que há picos, declínios e espaçamentos em diferentes períodos, o que pode evidenciar fenômenos dessa relação, como: brigas, maior aproximação, viagens.

Média de mensagens por dia da semana

O objetivo do próximo gráfico é investigar qual o dia da semana apresenta a maior média de mensagens enviadas. Ou seja, qual dia da semana os usuários mais se falam em média.

A primeira etapa é contabilizar o número de semanas (variável “weeks”). Em seguida, vamos criar um subset chamado “wd”, que conterá a média de mensagens por dia da semana. Veja o código abaixo:

weeks <- as.numeric(min(chat$date) %--% max(chat$date) , "weeks")wd <- chat %>%
mutate(day = weekdays(date, abbreviate = FALSE)) %>%
group_by(day) %>%
summarise(n = n(), avg = n() / weeks)%>%
mutate(day = ordered(day,levels = c(
"sábado","sexta-feira", "quinta-feira","quarta-feira",
"terça-feira","segunda-feira","domingo")))
ggplot(wd, aes(x = day, y = avg)) +
geom_bar(aes(fill = day), show.legend = FALSE,
stat = "identity") +
geom_text(aes(
x = day,
y = (avg + 8),
label = round(avg, 1)
)) +
labs(x = "Dia da Semana",
y = "") +
theme_hc() +
theme(
line = element_line(colour = "black"),
panel.grid.minor.y = element_line(size = 0),
panel.grid.major.y = element_line(size = 0)
) +
coord_flip() +
scale_y_continuous(position = "right")

Esse gráfico demonstra que o dia da semana mais falado é a quinta-feira, seguida da terça-feira e quarta-feira. Esse dado pode evidenciar o comportamento dos usuários, como, por exemplo, os dias da semana com maior ou menor contato presencial.

Volume de mensagens ao longo do dia

E qual o horário do dia que os usuários mais conversam em média? É exatamente isso que vamos observar no próximo gráfico.

Diferentemente do gráfico anterior, vamos precisar contar o número de dias desde o início da conversa (variável “days”). Em seguida, vamos criar um subset chamado “tod”, que conterá a média de mensagens por minuto do dia. Veja que o gráfico contém muitas informações, por isso foi implementado a função de interação do Plotly e labels (eixo x) em horas. Veja o código abaixo:

days <- as.numeric(min(chat$date) %--% max(chat$date) , "days")tod <- chat %>%
mutate(
hour = as.numeric(substr(hours, 1, 2)),
min = as.numeric(substr(hours, 4, 5)),
sec = as.numeric(substr(hours, 7, 8)),
Minuto = (hour * 60) + min
) %>%
count(Minuto) %>%
mutate(Media = n / days)
fig2 <-
ggplot(tod, aes(x = Minuto,
y = Media)) +
geom_line(color = "#F8766D") +
geom_smooth(se = FALSE, color = "#00BFC4") +
labs(x = "Horário do dia",
y = "Média de mensagens (por minuto)") +
scale_x_continuous(
breaks = seq(from = 0, to = 1380, by = 60),
labels = c(
"Meia-noite",
paste0(seq(
from = 1, to = 11, by = 1
), "am"),
"Meio-dia",
paste0(seq(
from = 1, to = 11, by = 1
), "pm")
)
) +
theme_hc() +
theme(axis.text.x = element_text(angle = 45))
ggplotly(fig2)

Ao observar esse gráfico, como um todo, é possível observar que os usuários conversam, predominantemente, durante o dia. Nesse caso, em especial, parece que os usuários não conversam com maior frequência durante o horário comercial. Sendo o horário mais conversado, em média, no período das 7 pm.

Emojis usados com maior frequência

A comunicação é realmente incrível, além de enviar texto e áudios, podemos enviar recursos de mídia gráficos como os emojis. Eu particularmente adoro utilizá-los, porque deixa a conversa on-line mais afável.

A próxima análise consiste em identificar, entre os usuários, os 5 emojis mais utilizados.

Por estarmos lidando com texto, a imagem do emoji fica prejudicada e para colocarmos a imagem do emoji no gráfico, precisamos baixar a imagem dos emojis para colocarmos no gráfico. Esse procedimento é evidenciado no objeto “emoji_data”. O código abaixo mostra como realizar esse e os demais procedimentos da construção do gráfico.

emoji_data <- rwhatsapp::emojis %>%
mutate(hex_runes1 = gsub("\\s[[:alnum:]]+", "", hex_runes)) %>%
mutate(emoji_url = paste0(
"https://abs.twimg.com/emoji/v2/72x72/",
tolower(hex_runes1),
".png"
))
chat %>%
unnest(emoji) %>%
count(author, emoji, sort = TRUE) %>%
group_by(author) %>%
top_n(n = 5, n) %>%
left_join(emoji_data, by = "emoji") %>%
ggplot(aes(
x = reorder(emoji, n),
y = n,
fill = author
)) +
geom_col(show.legend = FALSE) +
ylab("") +
xlab("") +
coord_flip() +
geom_image(aes(y = n + 20, image = emoji_url)) +
facet_wrap(~ author, ncol = 2, scales = "free_y") +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank())

Observando o gráfico de emojis é possível ver algumas características individuais de cada usuário. A Pessoa1 parece utilizar mais emojis e parece se divertir muito com o Usuário2. Já o Usuário2 utiliza mais emojis com corações (amorosos) do que o usuário1.

Nuvem de palavras

Uma nuvem de palavras consegue demonstrar as palavras mais frequentemente utilizadas em um texto. Consequentemente, você consegue ter uma noção do vocabulário e dos assuntos falados em um texto.

A nossa próxima análise será uma nuvem de palavras comparativa, sendo de um lado uma pessoa e do outro lado a outra pessoa. Essa maravilha é possível graças à função “comparison.cloud()” do pacote “wordcloud”.

Antes de iniciar as análises, precisamos remover as palavras menos relevantes (stopword) e que podem atrapalhar nossa análise. Para isso, todas essas palavras são listadas em “to_remove”, você pode colocar mais palavras se necessário. Em seguida, um subset com a frequência das palavras por usuário foi criado. Veja o código abaixo:

to_remove <- c(stopwords('pt'),"q",'w',"htps","pra","tá","vc",               "k","n","nao","sim","Arquivo","de","mídia","oculto","arquivo","c",'ta','to','vou','tão','pq','eh','https','ja','tb',"tbm","vai","iso","mto","isso","acho","td","haha","hahaha",'rsrs','kk','é','ti','tô')words <- chat %>%
filter(!is.na(text)) %>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% to_remove) %>%
count(author, word, sort = TRUE) %>%
group_by(author)
matrix <- acast(words, word ~ author, fill = 0)
comparison.cloud(matrix, max.words = 50)

Comparando a nuvem de palavras é possível conhecer um pouco mais os usuários. Podemos observar que a Pessoa1 e a Pessoa2 utilizam expressões diferentes durante a sua comunicação.

Diversidade lexical na conversa

A diversidade lexical refere-se à diversidade de palavras utilizadas no diálogo. Quanto maior é o número de palavras diferentes utilizadas pelo sujeito, maior é a sua diversidade lexical.

Portanto, a nossa última análise pretende observar entre os usuários qual tem maior diversidade lexical.

Para isso, precisamos contar as palavras únicas em todo texto. Em seguida, verificar a quantidade de vezes que um usuário utilizou essa palavra. Aquele que utilizou mais palavras únicas, apresenta maior diversidade lexical.

Lembrando que o objeto criado anteriormente “to_remove” está sendo utilizado aqui para remover palavras irrelevantes. Veja como implementar no código abaixo:

chat%>%
unnest_tokens(input = text,
output = word) %>%
filter(!word %in% to_remove) %>%
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("Diversidade Lexical") +
xlab("Usuário") +
coord_flip()

O gráfico mostra que a Pessoa1 utiliza mais palavras diferentes do que a Pessoa2, evidenciando maior diversidade lexical. Essa habilidade pode ser influenciada por questões diversas da vida, mas na análise, pode haver ainda a questão das palavras erradas. Pode a Pessoa1 ter mais palavras erradas do que a Pessoa2 e consequentemente ter mais palavras únicas.

Considerações Finais

Nesse artigo visualizamos algumas análises que mostram a potencialidade da análise de conversas do WhatsApp. Por meio dessas análises é possível visualizar eventos importantes da relação, características e comportamentos dos usuários.

Particularmente, eu me surpreendi com esse tipo de análise. Testando os meus próprios dados eu pude perceber diversos padrões interessantes e únicos de cada relação. E você? Gostou também de analisar os seus dados?

Espero que tenha gostado e qualquer dúvida, comentário ou observação são muito bem-vindos! Fique à vontade para se manifestar e vamos aprender juntos! Se preferir, você pode me contatar pelo dalton.bc96@gmail.com

Obrigado pela leitura!

--

--