Artikel ini merupakan bagian dari Exploratory Data Analysis untuk pengembangan dashboard AKSATA
. Query twitter search “Quweenjojo” menarik untuk dibahas karena pemilik akun twitter “Quweenjojo” sempat menjadi pusat perhatian warganet pada pertengahan 2021 dan Awal Februari 2022 yang lalu.
::include_graphics("input/jojoquween.png") knitr
Tweet permintaan maaf yang viral pada awal Februari 2022 membawa warganet teringat dengan pernyataan Quweenjojo pada pertengahan tahun 2021 lalu. Saat itu ia mengklaim bahwa telah mendapat perlakuan kurang pantas (pelecehan seksual) dari seorang penyiar radio bernama Gofar Hilman, pada tahun 2018.
Reaksi warganet menanggapi viralnya kembali Quweenjojo cukup beragam. Pada umumnya mereka bingung untuk menentukan standing positionnya terhadap kasus ini–antara merasa bingung atas sikap Quweenjojo; ada yang mencurigai Gofar Hilman memaksa Quweenjojo memberikan pernyataan palsu; ada pula yang prihatin dan memberi semangat terhadap kondisi kesehatan mental Quweenjojo.
Memang sempat diakui kalau Quweenjojo menderita skizofrenia, dan sering mengalami hal-hal delusional.
Terlepas dari sentimen warganet, Analisis SNA ini dibuat untuk memahami pola pembicaraan yang terbentuk berdasarkan aktivitas mention/replies maupun quote tweet.
Data diambil menggunakan bahasa pemrograman R dan package Rtweet
. Anda dapat melihat dokumentasi https://github.com/ropensci/rtweet untuk mengambil data melalui API twitter (open in new tab).
Dataset diambil beberapa hari pasca viralnya tweet, dengan jumlah observasi yang didapatkan sebanyak 10294 tweets.
library(tidyverse)
library(igraph)
library(sigmajs)
library(graphTweets)
<- readRDS("quweenjojo.rds")
raw_data glimpse(raw_data)
#> Rows: 10,294
#> Columns: 35
#> $ created_at <chr> "Sat Feb 12 05:37:48 +0000 2022", "Fri F~
#> $ id <dbl> 1492372346107473920, 1492171619892338688~
#> $ id_str <chr> "1492372346107473921", "1492171619892338~
#> $ full_text <chr> "Selain kamera yang dipasang si Mbak seb~
#> $ truncated <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE~
#> $ display_text_range <dbl> 181, 61, 66, 51, 63, 140, 23, 77, 140, 5~
#> $ entities <list> [[<data.frame[1 x 2]>], [<data.frame[1 ~
#> $ metadata <list> [<data.frame[1 x 2]>], [<data.frame[1 x~
#> $ source <chr> "<a href=\"https://mobile.twitter.com\" ~
#> $ in_reply_to_status_id <dbl> NA, NA, NA, 1492175242235871232, 1493196~
#> $ in_reply_to_status_id_str <chr> NA, NA, NA, "1492175242235871233", "1493~
#> $ in_reply_to_user_id <dbl> NA, NA, NA, 719755682908491776, 11192604~
#> $ in_reply_to_user_id_str <chr> NA, NA, NA, "719755682908491781", "11192~
#> $ in_reply_to_screen_name <chr> NA, NA, NA, "kincir_mainan", "beruangbes~
#> $ geo <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ coordinates <list> [<data.frame[1 x 3]>], [<data.frame[1 x~
#> $ place <list> [<data.frame[1 x 3]>], [<data.frame[1 x~
#> $ contributors <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ is_quote_status <lgl> TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, ~
#> $ quoted_status_id <dbl> 1492135004373405696, NA, 149213500437340~
#> $ quoted_status_id_str <chr> "1492135004373405698", NA, "149213500437~
#> $ quoted_status <list> [<data.frame[1 x 27]>], [<data.frame[1 ~
#> $ retweet_count <dbl> 736, 401, 86, 0, 0, 1, 0, 663, 7809, 0, ~
#> $ favorite_count <dbl> 3539, 4552, 494, 0, 0, 0, 0, 0, 0, 0, 0,~
#> $ favorited <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE~
#> $ retweeted <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE~
#> $ possibly_sensitive <lgl> FALSE, FALSE, FALSE, NA, NA, NA, FALSE, ~
#> $ lang <chr> "in", "in", "in", "en", "in", "in", "und~
#> $ retweeted_status <list> [<data.frame[1 x 30]>], [<data.frame[1 ~
#> $ text <chr> "Selain kamera yang dipasang si Mbak seb~
#> $ favorited_by <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ display_text_width <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ quoted_status_permalink <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ query <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ possibly_sensitive_appealable <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
Package rtweet
versi 0.7.900 menghasilkan metadata yang berbeda dengan versi sebelumnya. Metadata Rtweet versi terbaru berbentuk nested dataframe. Maka dari itu, saya harus menormalisasi data ke bentuk yang lebih sederhana dan mudah digunakan untuk clustering.
# Subset dan normalisasi variabel "retweeted status"
<- raw_data %>%
ret_status_user select(retweeted_status) %>%
unnest_wider(retweeted_status) %>%
rename(created_at_retweet = created_at) %>%
rename(id_ret = id) %>%
rename(id_str_ret = id_str) %>%
select(
-entities,
-lang,
-metadata,
-source,
-truncated,
-in_reply_to_status_id,
-in_reply_to_status_id_str,
-in_reply_to_user_id
%>%
) rename(text_ret = full_text) %>%
unnest_wider(user) %>%
rename(description_user = description) %>%
rename(attached_url = url) %>%
# select(-...1) %>%
unnest_wider(entities) %>%
select(
-display_text_range,
-description,
-quoted_status,
-extended_entities,
-place,
-withheld_in_countries
)
# List "user_mentions" terdapat pada variabel entities, saya harus mengubahnya menjadi list
<- raw_data %>%
to_mentions select(entities) %>%
mutate(entities = as.list(entities))
head(to_mentions)
screen_name
di dalam list entities
dan user_mentions
<- lapply(to_mentions$entities, function(x) {x[["user_mentions"]]$screen_name})
list_mention
# Mengubah hasil subset menjadi character list c("","")
<- unlist(unlist(as.character(list_mention))) mentions_chr
# Settling object ret_status_user dengan menambahkan character list,
# menghilangkan tweet tanpa interaksi mention/reply
<- ret_status_user %>%
object_fix mutate(mentions_screen_name = mentions_chr)%>%
mutate(mentions_screen_name = ifelse(
== "NA",
mentions_screen_name NA,
as.character(mentions_screen_name))) %>%
drop_na(text_ret) %>%
mutate(mentions_screen_name = ifelse(mentions_screen_name == screen_name, NA, as.character(mentions_screen_name))) %>%
select(-url)
# Subset hanya variabel yang dibutuhkan
<- object_fix %>%
cleansing select(screen_name, mentions_screen_name, name)
# Mengkonversi character list c("","") menggunakan notasi regular expression
<-
tweets %>%
cleansing mutate(
mentions_screen_name = str_replace_all(
string = mentions_screen_name,
pattern = "^c\\(|\\)$",
replacement = ""
)%>%
) separate_rows(mentions_screen_name, sep = ",") %>%
na.omit() %>%
mutate(
mentions_screen_name = str_replace_all(
string = mentions_screen_name,
pattern = "[[:]]+",
replacement = ""
)%>%
) rename(from = screen_name,
to = mentions_screen_name) %>%
mutate(to = str_replace_all(
string = to,
#to,
pattern = "\"",
replacement = ""
))
tweets
graphTweets
dan SigmaJs
<- tweets %>%
gt gt_edges(from, to) %>%
gt_nodes() %>%
gt_collect()
# transform ke dataframe nodes dan edges (agar nantinya mudah dibaca oleh shiny)
<- gt$nodes %>% as.data.frame()
tmp_nodes
<- gt$edges %>% as.data.frame()
tmp_edges
<- tmp_nodes %>%
nodes mutate(
id = nodes,
label = nodes,
size = n,
color = "#337def"
)
<- tmp_edges %>%
edges mutate(id = 1:n())
sigmajs() %>%
sg_force_start() %>%
sg_nodes(nodes, id, label, size, color) %>%
sg_edges(edges, id, source, target) %>%
sg_force_stop(15000)
Nodes dari visualisasi ini hoverable (untuk melihat username pada klaster). Visualisasi juga dapat di zoom sesuai keinginan.
Dapat kita lihat bahwa interaksi warganet pada topik “Quweenjojo” membentuk satu klaster utama dan beberapa klaster clique/ngerumpi. Klaster utama berisikan orang-orang yang secara jelas menyebut nama akun “@quweenjojo” di dalam tweetnya. Dalam kata lain, dapat kita simpulkan bahwa lebih banyak reaksi warganet yang langsung membalas tweet klarifikasi dari quweenjojo; daripada mereka yang melakukan “quote tweet” secara tidak langsung.
Berdasarkan visualisasi di atas, terdapat beberapa klaster “clique” yang berbentuk nodes-nodes kecil di sekeliling klaster besar. Pada topik ini, clique terbentuk dari interaksi tidak langsung atau “quote tweet”.
<-
target c(
"HanienNia",
"Aermani_",
"AdalardBanim",
"agusatriawibawa",
"LaxusRalenion",
"chumaidijusuf",
"fairyfoxlady",
"_bernacleboy",
"cyborgrunge",
"riodwinurhafizh"
)
%>%
object_fix distinct() %>%
select(text_ret, screen_name, mentions_screen_name, id_str_ret) %>%
filter(screen_name %in% target)
::include_graphics("input/ngurahsaka.png") knitr
::include_graphics("input/komnasperempuan.png") knitr
library(dplyr)
<-
target2 c(
"ngurahsaka",
"komnasperempuan",
"sentrisman",
"f_andhikaa",
"ence_dwi",
"araghutama",
"adefs97",
"backfirecricket"
)
%>%
object_fix distinct() %>%
select(text_ret, screen_name, mentions_screen_name, id_str_ret) %>%
filter(screen_name %in% target2)
Berdasarkan hasil visualisasi SNA dan inspect tweets, ternyata narasi yang dikemukakan antara klaster clique dengan klaster utama sedikit berbeda. Klaster clique lebih didominasi mereka yang sudah memiliki standing position terhadap topik: antara mengambil sikap netral, negatif, atau justru ingin memperluas diskursus (secara terpisah) dengan circle mereka sendiri.
Besar dan terpusatnya visualisasi klaster utama pada satu username (yakni Quweenjojo), melambangkan banyaknya orang yang merespon tweet Quweenjojo secara langsung; juga dengan narasi yang sifatnya langsung pula (seperti: “I don’t get it…”; “Ok now im real worried, i hope you’re okay and not under any pressure…”)
Berfokus pada pemilik akun Quweenjojo, sudah tentu apa yang ia lakukan membuat kegaduhan di media sosial dan kehidupan orang yang tertuduh. Namun, kira-kira sekitar satu minggu setelah viralnya tweet permintaan maaf, Gofar Hilman menceritakan kondisi Quweenjojo yang sesungguhnya, di dalam sebuah podcast.
Bagi penderita gangguan mental, mengakui kesalahan merupakan tindakan yang sulit dan patut kita apresiasi.
Hanya mereka yang bertanggung jawab menangani kesehatan mental Quweenjojo yang mampu memberi keterangan dengan lebih jelas. Namun pasti, sifat dari informasi tersebut sangatlah personal.