Comunidade R Brasil no Telegram

O que faz o R ser tão legal é a comunidade que está por trás dela. Existem várias formas de acessar essa comunidade: pelo stackoverflow, twitter, facebook, entre outras. Nesse post vou falar um pouquinho sobre a comunidade RBrasil no telegram, usando dados!

A comunidade @rbrasiloficial foi criada em 2015 pelo Felipe Barros e já tem mais de mil inscritos. O canal é utilizado para tirar dúvidas, discutir sobre o futuro do R, divulgar trabalhos e dar pitacos sobre as coisas que estão acontecendo.

Nesse post vou mostrar como importar e arrumar os dados, e algumas visualizações da base de conversas do Telegram.

Importando os dados

O Telegram já possui uma ferramenta para exportar os chats. Basta clicar nas opções do chat e mandar exportar. Então vou assumir que esses dados já estão em mãos.

Os dados estão disponíveis no formato HTML. Para ler um arquivo, montei o seguinte código:

library(magrittr)

ler_html_telegram <- function(html_file) {
  # pega todas as mensagens
  divs <- xml2::read_html(html_file) %>% 
    xml2::xml_find_all("//div[@class='message default clearfix']")
  
  # nome da pessoa
  nomes <- divs %>% 
    xml2::xml_find_all("./div/div[@class='from_name']") %>% 
    xml2::xml_text() %>% 
    stringr::str_squish()
  
  # data e hora da mensagem
  data_horas <- divs %>% 
    xml2::xml_find_all("./div/div[@class='pull_right date details']") %>% 
    xml2::xml_attr("title") %>% 
    lubridate::dmy_hms()
  
  # texto da mensagem
  textos <- divs %>% 
    purrr::map(xml2::xml_find_first, "./div/div[@class='text']") %>% 
    purrr::map_chr(xml2::xml_text) %>% 
    stringr::str_squish()
  
  # retorna numa tabela
  tibble::tibble(
    data_hora = data_horas,
    nome = nomes,
    texto = textos
  )
}

Depois, basta listar todos os arquivos e carregar cada arquivo usando purrr::map_dfr():

path <- "~/Downloads/Telegram Desktop/ChatExport_17_08_2019/"
todos_arquivos <- fs::dir_ls(path, regexp = "messages")

d_msg <- purrr::map_dfr(
  todos_arquivos, 
  ler_html_telegram, 
  .id = "arquivo"
)

No final, fiquei com uma base de dados com 26.980 linhas e 4 colunas.

Contas deletadas ganharam no volume de mensagens… Mas acho que não queremos considerá-las pois temos várias pessoas nessa contagem. O grande Marcelo Ventura Freire venceu no número de mensagens! Eu também estou no páreo :)

d_msg %>% 
  dplyr::count(nome, sort = TRUE) %>% 
  dplyr::mutate(prop = scales::percent(n/sum(n))) %>% 
  head(10) %>% 
  knitr::kable()
nome n prop
Deleted Account 3101 11.5%
Marcelo Ventura Freire 2313 8.6%
Charles Lula da Silva 1897 7.0%
Leonard de Assis 1677 6.2%
Sillas Gonzaga 1540 5.7%
Julio Trecenti 1130 4.2%
Bruna Wundervald 951 3.5%
Andre Mesquita 818 3.0%
Fernando Barbalho 696 2.6%
George Santiago 611 2.3%

E no tempo, como que fica? Parece que no início o volume de mensagens era mais alto, e depois entramos num patamar estável.

library(ggplot2)
d_msg %>% 
  dplyr::mutate(mes = lubridate::floor_date(data_hora, "month")) %>% 
  dplyr::count(mes) %>% 
  ggplot(aes(x = mes, y = n)) +
  geom_line() +
  geom_point() +
  theme_minimal(16)

No gráfico seguinte, peguei as doze pessoas que falaram mais historicamente e avaliei a evolução mensal de mensagens. Temos de tudo: os constantes, os que sumiram, os que ressurgiram das cinzas e os que chegaram para ficar.

d_msg %>% 
  dplyr::filter(nome != "Deleted Account") %>% 
  dplyr::mutate(nome = forcats::fct_lump(nome, 12),
                nome = as.character(nome),
                mes = lubridate::floor_date(data_hora, "month")) %>% 
  dplyr::filter(nome != "Other") %>% 
  dplyr::count(mes, nome, sort = TRUE) %>% 
  tidyr::complete(mes, nome, fill = list(n = 0)) %>% 
  ggplot(aes(x = mes, y = n)) +
  geom_line() +
  facet_wrap(~nome) +
  labs(x = "Mês", y = "Quantidade de mensagens") +
  theme_bw()

E qual é o horário que as pessoas interagem mais? Parece que é às 16 horas, aquele horário que a pessoa está ferrada no trabalho e precisa pedir uma ajuda aos amigos…

d_msg %>% 
  dplyr::mutate(hora = factor(lubridate::hour(data_hora))) %>% 
  ggplot(aes(x = hora)) +
  geom_bar(fill = "royalblue") +
  theme_minimal(14) +
  ggtitle("Hora das mensagens")

E o dia da semana? Terça-feira wins!

d_msg %>% 
  dplyr::mutate(wd = lubridate::wday(data_hora, label = TRUE)) %>% 
  ggplot(aes(x = wd)) +
  geom_bar(fill = "pink2") +
  theme_minimal(14) +
  ggtitle("Dia da semana das mensagens")

E claro, não poderia faltar um wordcloud…

# dá pra criar funções anônimas assim ;)
# esse é um limpador bem safado que fiz em 1 min
limpar <- . %>% 
  abjutils::rm_accent() %>% 
  stringr::str_to_title() %>% 
  stringr::str_remove_all("[^a-zA-Z0-9 ]") %>% 
  stringr::str_squish()

# tirar palavras que nao quero
banned <- tidytext::get_stopwords("pt") %>% 
  dplyr::mutate(palavra = limpar(word))

cores <- viridis::viridis(10, begin = 0, end = 0.8)

d_msg %>% 
  tidytext::unnest_tokens(palavra, texto) %>% 
  dplyr::mutate(palavra = limpar(palavra)) %>% 
  dplyr::anti_join(banned, "palavra") %>% 
  dplyr::count(palavra, sort = TRUE) %>% 
  with(wordcloud::wordcloud(
    palavra, n, scale = c(5, .1), 
    min.freq = 80, random.order = FALSE,
    colors = cores
  ))

Fiz poucos gráficos para te deixar com vontade de brincar mais. Gostou da brincadeira? Então faça suas próprias análises do seu chat preferido do Telegram!

É isso. Happy coding ;)

comments powered by Disqus