1 Packages

library(tm)
## Warning: package 'tm' was built under R version 4.3.3
## Loading required package: NLP
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(wordcloud)
## Warning: package 'wordcloud' was built under R version 4.3.3
## Loading required package: RColorBrewer
library(ggplot2)
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:NLP':
## 
##     annotate
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(tidytext)
## Warning: package 'tidytext' was built under R version 4.3.3
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.3.3
library(readr)
library(stringr)
library(syuzhet)
## Warning: package 'syuzhet' was built under R version 4.3.3
library(text)
## Warning: package 'text' was built under R version 4.3.3
## This is text (version 1.2.1).
## Text is new and still rapidly improving.
##                
## Newer versions may have improved functions and updated defaults to reflect current understandings of the state-of-the-art.
##                Please send us feedback based on your experience.
## 
## For more information about the package see www.r-text.org.
library(ggplot2)
library(ggrepel)
library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:syuzhet':
## 
##     rescale
## The following object is masked from 'package:readr':
## 
##     col_factor
library(viridis)
## Loading required package: viridisLite
## 
## Attaching package: 'viridis'
## The following object is masked from 'package:scales':
## 
##     viridis_pal

2 Import Data

tiktok <- read_csv("C:/Users/Ratu Risha/Documents/tiktoknih.csv")
## Rows: 210 Columns: 9
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (7): _id, comments, followers, influencer, likes, shares, view
## dbl  (1): rank
## dttm (1): time_scraped
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

3 Praprocessing Data

3.1 Menghapus Duplikasi Data

# Menghitung data asli
jumlahdata <- nrow(tiktok)

# Menghapus Duplikasi
tiktok_clean <- tiktok %>% distinct(influencer, .keep_all = TRUE)

# Menghitung data yang sudah bersih
jumlahdataclean <- nrow(tiktok_clean)

# Data Frame
jumlah_data <- data.frame(
  Data = c("Sebelum", "Sesudah"),
  Jumlah = c(jumlahdata, jumlahdataclean)
)
jumlah_data
##      Data Jumlah
## 1 Sebelum    210
## 2 Sesudah     23
ggplot(jumlah_data, aes(x = Data, y = Jumlah, fill = Data)) +
  geom_bar(stat = "identity", color = "white", width = 0.7) +
  geom_text(aes(label = Jumlah), vjust = -0.5, color = "black", size = 5) +
  scale_fill_manual(values = c("Sebelum" = "#6A5ACD", "Sesudah" = "#4682B4")) + # SlateBlue and SteelBlue
  coord_flip() +
  labs(title = 'Jumlah Data', x = "Data", y = "Jumlah") +
  theme_minimal() +
  theme(
    plot.background = element_rect(fill = "white"),
    panel.background = element_rect(fill = "white"),
    panel.grid.major = element_line(color = "grey90"),
    panel.grid.minor = element_blank(),
    axis.text = element_text(color = "black"),
    axis.title = element_text(color = "black"),
    plot.title = element_text(color = "black", hjust = 0.5, size = 15, face = "bold"),
    panel.border = element_rect(color = "grey80", fill = NA, size = 1.5),
    legend.position = "none"
  )
## Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

print(tiktok_clean)
## # A tibble: 23 × 9
##    `_id`    comments followers influencer likes  rank shares time_scraped       
##    <chr>    <chr>    <chr>     <chr>      <chr> <dbl> <chr>  <dttm>             
##  1 66581dc… 35.6K    4.2M      "janneksp… 3.7M      2 341.3K 2024-05-30 06:33:38
##  2 66581dc… 26.1K    3M        "nikolais… 11.7M     1 299K   2024-05-30 06:33:38
##  3 66581dc… 8.9K     98.8K     "sobrizzl… 2M        4 130.1K 2024-05-30 06:33:38
##  4 66581dc… 6.3K     4M        "avascrea… 2M        5 89.8K  2024-05-30 06:33:38
##  5 66581dc… 15.6K    14.7M     "tuvok12\… 3.1M      3 42.7K  2024-05-30 06:33:38
##  6 66592ed… 5.9K     2M        "katieflo… 2M        4 364K   2024-05-31 01:58:53
##  7 665e751… 9K       10.9M     "anthonny… 1.9M      2 62K    2024-06-04 01:59:42
##  8 665e751… 9.9K     21M       "livbedum… 2.6M      3 31K    2024-06-04 01:59:42
##  9 665fc67… 8.6K     152.6K    "holadoci… 1.9M      2 124K   2024-06-05 01:59:17
## 10 666117f… 10.4K    12.5M     "thebrand… 1.3M      5 141.9K 2024-06-06 01:59:22
## # ℹ 13 more rows
## # ℹ 1 more variable: view <chr>

3.2 Convert Data ke Numerik

# Convert the relevant columns to numeric
convert_to_numeric <- function(x) {
  as.numeric(gsub("K", "e3", gsub("M", "e6", x)))
}

jumlah_data <- tiktok_clean %>%
  mutate(
    comments = convert_to_numeric(comments),
    followers = convert_to_numeric(followers),
    likes = convert_to_numeric(likes),
    shares = convert_to_numeric(shares),
    view = convert_to_numeric(view)
  )
print(jumlah_data)
## # A tibble: 23 × 9
##    `_id`   comments followers influencer  likes  rank shares time_scraped       
##    <chr>      <dbl>     <dbl> <chr>       <dbl> <dbl>  <dbl> <dttm>             
##  1 66581d…    35600   4200000 "janneksp… 3.7 e6     2 341300 2024-05-30 06:33:38
##  2 66581d…    26100   3000000 "nikolais… 1.17e7     1 299000 2024-05-30 06:33:38
##  3 66581d…     8900     98800 "sobrizzl… 2   e6     4 130100 2024-05-30 06:33:38
##  4 66581d…     6300   4000000 "avascrea… 2   e6     5  89800 2024-05-30 06:33:38
##  5 66581d…    15600  14700000 "tuvok12\… 3.10e6     3  42700 2024-05-30 06:33:38
##  6 66592e…     5900   2000000 "katieflo… 2   e6     4 364000 2024-05-31 01:58:53
##  7 665e75…     9000  10900000 "anthonny… 1.9 e6     2  62000 2024-06-04 01:59:42
##  8 665e75…     9900  21000000 "livbedum… 2.6 e6     3  31000 2024-06-04 01:59:42
##  9 665fc6…     8600    152600 "holadoci… 1.9 e6     2 124000 2024-06-05 01:59:17
## 10 666117…    10400  12500000 "thebrand… 1.3 e6     5 141900 2024-06-06 01:59:22
## # ℹ 13 more rows
## # ℹ 1 more variable: view <dbl>

4 Visualisasi Data

4.1 Followers Per Influencer

ggplot(jumlah_data, aes(x = reorder(influencer, -followers), y = followers, fill = influencer)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = scales::comma(followers)), vjust = -0.3, size = 3, angle = 90, hjust = 1) +
  labs(title = "Followers per Influencer", x = "Influencer", y = "Followers") +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5),
    plot.title = element_text(hjust = 0.5)
  ) +
  scale_fill_discrete(guide = FALSE)
## Warning: The `guide` argument in `scale_*()` cannot be `FALSE`. This was deprecated in
## ggplot2 3.3.4.
## ℹ Please use "none" instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

4.2 Followers vs Likes

ggplot(jumlah_data, aes(x = followers, y = likes)) +
  geom_hex(bins = 30, aes(fill = ..count..)) +
  scale_fill_viridis_c(option = "plasma", name = "Count") + # Using a colorblind-friendly palette
  labs(title = "Followers vs Likes", x = "Followers", y = "Likes") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
    axis.title = element_text(size = 15, face = "bold"),
    axis.text = element_text(size = 12),
    panel.grid.major = element_line(color = "grey80"),
    panel.grid.minor = element_blank(),
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA)
  ) +
  scale_x_continuous(labels = scales::comma) + 
  scale_y_continuous(labels = scales::comma)
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

4.3 Views vs Comments

ggplot(jumlah_data, aes(x = view, y = comments, color = influencer)) +
  geom_point(aes(size = comments), alpha = 0.7) +  # Size of points scaled by comments
  geom_text_repel(aes(label = influencer), size = 3, box.padding = 0.5, point.padding = 0.5, max.overlaps = 10) +
  scale_color_viridis_d(option = "plasma") + # Using a colorblind-friendly palette
  scale_size(range = c(5, 15), guide = FALSE) + # Increase the range of point sizes
  labs(title = "Views vs Comments", x = "Views", y = "Comments") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
    axis.title = element_text(size = 15, face = "bold"),
    axis.text = element_text(size = 12),
    legend.position = "none",
    panel.grid.major = element_line(color = "grey80"),
    panel.grid.minor = element_blank(),
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA)
  ) +
  scale_x_continuous(labels = scales::comma) + 
  scale_y_continuous(labels = scales::comma)
## Warning: ggrepel: 9 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

4.4 Plot Likes vs Shares

ggplot(jumlah_data, aes(x = likes, y = shares, color = influencer)) +
  geom_point(size = 3) +
  labs(title = "Likes vs Shares", x = "Likes", y = "Shares") +
  theme_minimal()

4.5 Rank Per Influencer

ggplot(jumlah_data, aes(x = reorder(influencer, rank), y = rank)) +
  geom_segment(aes(xend = influencer, yend = 0), color = "grey") +
  geom_point(size = 5, aes(color = influencer), alpha = 0.7) +
  scale_color_viridis_d(option = "plasma") + # Using a colorblind-friendly palette
  coord_flip() +
  labs(title = "Rank of Each Influencer", x = "Influencer", y = "Rank") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
    axis.title = element_text(size = 15, face = "bold"),
    axis.text = element_text(size = 12),
    legend.position = "none",
    panel.grid.major = element_line(color = "grey80"),
    panel.grid.minor = element_blank(),
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA)
  )

4.6 Shares Per Influencer

ggplot(jumlah_data, aes(x = reorder(influencer, shares), y = shares, fill = influencer)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = scales::comma(shares)), hjust = -0.1, size = 3) +
  scale_fill_viridis_d(option = "plasma", guide = FALSE) + # Using a colorblind-friendly palette
  coord_flip() +
  labs(title = "Shares per Influencer", x = "Influencer", y = "Shares") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 20, face = "bold"),
    axis.title = element_text(size = 15, face = "bold"),
    axis.text = element_text(size = 12),
    panel.grid.major = element_line(color = "grey80"),
    panel.grid.minor = element_blank(),
    plot.background = element_rect(fill = "white", color = NA),
    panel.background = element_rect(fill = "white", color = NA)
  ) +
  scale_y_continuous(labels = scales::comma)