Rselenium Intro





In this article, we will learn to do web scraping using RSelenium. RSelenium provides R bindings for the Selenium Webdriver API. Selenium is a project focused on automating web browsers. RSelenium allows you to carry out unit testing and regression testing on your webapps and webpages across a range of browser/OS combinations. You can access full vignettes of RSelenium here.

R also provide web scrapping tools like the famous rvest but RSelenium gives more advantages than rvest, for example:

  • Java scripted web scrapping

  • Running on selenium server with Docker container
  • Running on local by Webdriver Manager or wdman wrapper
  • Injectting java script to transform HTML structure
  • Sending Events to elements (click, choose dropdown menu, scrolling, sending text, etc.)
  • Live browsing navigation

Web scraping is just on of various data gathering technique. Why it’s important to do data gathering? well.. doesn’t matter how ‘expert’ you’re as data scientist, if there’s no data, what you gonna do?



Background

Objective

The goal of this project is gather information as much as possible from Shopee product review. Shopee is a well-known marketplace in Indonesia and Asia. Every content in Shopee website are built using java script so it is almost impossible to do web scraping using HTML page source based tools like Rvest. We also want to do custom interaction like clicking next button or scrolling through the review. We’ll scrape all product with keyword Iphone X in Smartphone category. After we scrape the data, we will try to do a simple Exploratory Data Analysis to gain new information from the product reviews.

If you have no idea what is the difference between java scripted web than regular ones, you can try to scrape the shopee page using rvest and you will found nothing

library(rvest)
main <- "https://shopee.co.id/search?category=40&keyword=iphone%20x&subcategory=1211"
read_test <- read_html(main)
html_nodes(read_test,"a")
#> {xml_nodeset (0)}

In this case, you need to use web browser simulation tools like Selenium

Libraries

You can load the package into your workspace using the library() function

library(tidyverse)
library(rvest)
library(RSelenium)

Let’s begin

Prerequisites

From the vignettes, the author of RSelenium suggest to run selenium server by using Docker container rather than standalone binary. But is kinda hard to integrate Docker in our local pc and not all device (read: potato pc) can meet docker minimum requirements. So in this article we will run RSelenium with our default local browser. In this case, we will use Google Chrome as the browser.

We don’t need to install chrome webdriver to use RSelenium because this package provide rsDriver function which will manage the binaries needed for running a Selenium Server. In a simple words, it will download and install webdrive (based on your preferences) in your R environment.

First take a look at your chrome version Settings > About Chrome



I’m using Version 87.0.4280.66. we need to install webdriver with same version as our default browser. I also provide the main link to scrape the product.

main <- "https://shopee.co.id/search?category=40&keyword=iphone%20x&subcategory=1211"

# install webdriver and launh it in port 4444.
rsDriver(browser = "chrome",chromever = "87.0.4280.20",port = 4444L)

you can change the chrome version based on your default browser version. you can see the avaliable version of webdriver using binman::list_versions() function.

If there’s a browser popped up, You can ignore the warning message above

# assign the remote driver in rmdr object. rmdr will be your browser remote
rmdr <- remoteDriver(browserName = "chrome")
# open the browser
rmdr$open()
# navigate to main link
rmdr$navigate(main)



Information Gathering

Gather Product Pages

The chunk below provides functions to scrape the product. RSelenium also match elements by its css or xpath style. It really works like rvest. So if you already familiar with rvest, you can use selenium easily. Fear not if you don’t. You can learn how rvest works from my previous article here. The thing is we need to know css/xpath style from coresponding elements to gather the data or sending event like click or scrolling.

In the chunk below, we combine Rselenium to interact with the browser and rvest to gather the information.

shop <- "https://shopee.co.id"
# how many page you want to scrap
paged <- 10
# link container
link_base <- data.frame()

for(i in 1:paged){
  message("Getting product link #",i,"/",paged)
  
  # go to main page and wait for 5 second
  if(i == 1){
    rmdr$navigate(main)
    Sys.sleep(10)
    }
  
  # scroll to bottom and wait for 5 second
  webElem <- rmdr$findElement("css", "body")
  webElem$sendKeysToElement(list(key = "end"))
  Sys.sleep(5)
  
  # get page source
  pages <- rmdr$getPageSource()[[1]]
  # get link with rvest
  read1 <- read_html(pages)
  linkx <- html_nodes(read1,".shopee-search-item-result__item") %>% 
  html_nodes("a") %>% html_attr("href")
  
  linkget <- paste(shop,linkx,sep = "") %>% data.frame()
  link_base <- rbind(link_base,linkget)
  
  # next page
  rmdr$findElement("css",".shopee-icon-button--right")$clickElement()
  Sys.sleep(5)
}

RSelenium with live browser also have a crucial disadvantage, that is time. Scrape the data using Selenium is like running a browser simulation with robot to do the task repeatedly. It takes a lot of time to load a lot of webpages. You can encounter this by using headless browser (Phantomjs) but it needs different vignette that (maybe) i’ll provide later.

# link_product <- link_base %>% distinct() %>% 
#   rename("link" = ".")

link_product <- readRDS("data_input/Rselenium-intro/product_link.rds")
head(link_product)
#>                                                                                                                              link
#> 1                      https://shopee.co.id/iPhone-X-256gb-Second-Normal-Fullset-Ex-Inter-free-asuransi-JNE-i.47745953.2055161396
#> 2                       https://shopee.co.id/iphone-X-64gb-second-fullset-Normal-Ex-Inter-free-asuransi-JNE-i.47745953.1887735183
#> 3                    https://shopee.co.id/iPhone-X-256Gb-second-fullset-normal-no-face-id-free-asuransi-JNE-i.47745953.5510545590
#> 4 https://shopee.co.id/iPhone-X-256GB-64GB-Second-Fulset-MULUS-EX-Inter-Ori-Battery-2-7-8-6-mAh-Silver-Gray-i.61376437.4312219803
#> 5             https://shopee.co.id/iphone-x-256gb-second-fullset-ex-inter-NO-FACE-ID-JNE-INSURANCE-INCLUDES-i.73370096.7705786775
#> 6              https://shopee.co.id/-TERMURAH-APPLE-IPHONE-X-SECOND-64GB-256GB-GREY-SILVER-ORIGINAL-GARANSI-i.10230608.1586990183

Gather Product Review and Details

Same as before, I already build a long function to scrape information including: product name, price, rating, description, and review. Every line of code will be explained to you, so you can re-use it on your own project.

desc_product <- data.frame()
datt <- data.frame()
review_product <- vector(mode = "list",length = nrow(link_product))


for(i in 1:nrow(link_product)){
  message("Getting product description #",i,"/",nrow(link_product))
  # go to the link in the list
  rmdr$navigate(link_product$link[i])
  Sys.sleep(5)
  
  # check if rating is exist. if there is no rating we will assume
  # that the product is never been sold and fill the value as "none"
  add_null_a <- FALSE
  tryCatch(rmdr$findElement("css","._2z6cUg")$getElementText(),
           error = function(e){add_null_a <<- TRUE})
  if(add_null_a){rating <- "none"}else{
    # get product rating
    rating <- rmdr$findElement("css","._2z6cUg")$getElementText()[[1]]
  }
  
  # check if sold is exist. if there is no rating we will assume
  # that the product is never been sold and fill the value as "none"
  add_null_b <- FALSE
  tryCatch(rmdr$findElement("css","._22sp0A")$getElementText(),
           error = function(e){add_null_b <<- TRUE})
  if(add_null_b){sold <- "none"}else{
    # get product sold
    sold <- rmdr$findElement("css","._22sp0A")$getElementText()[[1]]
  }
  
  # get product name
  name <- rmdr$findElement("css",".qaNIZv span")$getElementText()[[1]]
  # get product price
  price <- rmdr$findElement("css","._3n5NQx")$getElementText()[[1]]
  # get product description
  description <- rmdr$findElement("css","._2u0jt9 span")$getElementText()[[1]]
  # save the product details to dataframe
  temp <- data.frame(Name = name, Rating = rating, Price = price,
                     Sold = sold, desc = description, Link = link_product$link[i])
  desc_product <- rbind(desc_product,temp)
  
  # review
  ## check how many review are listed. if there is no review,
  ## the loop will skip to next iteration
  add_null_c <- FALSE
  tryCatch(rmdr$findElement("css",".M3KjhJ+ .M3KjhJ ._3Oj5_n")$getElementText(),
           error = function(e){add_null_c <<- TRUE})
  ## if review are existed, count the review to calculate how many
  ## next-button click is needed
  if(add_null_c){next}else{
    rev <- rmdr$findElement("css",".M3KjhJ+ .M3KjhJ ._3Oj5_n")$getElementText() %>%
      unlist() %>% as.numeric()
    rev <- ifelse(rev <= 6, 0, ifelse(rev <= 8 & rev >6, 1,round(rev/6)))

    # scroll to bottom to load the review and wait for 10 second
    webElem <- rmdr$findElement("css", "body")
    webElem$sendKeysToElement(list(key = "end"))
    Sys.sleep(3)
    webElem$sendKeysToElement(list(key = "page_up"))
    Sys.sleep(10)

    ## code if there are only < 6 review. we don't need to click next
    if(rev == 0){
      if(length(rmdr$findElements("css",".shopee-product-rating__content")) == 0){next}else{
        # review text
        reviewx <- rmdr$findElements("css",".shopee-product-rating__content")
        review <- unlist(lapply(reviewx,function(x) x$getElementText()))
        # review time
        timex <- rmdr$findElements("css",".shopee-product-rating__time")
        time <- unlist(lapply(timex,function(x) x$getElementText()))

        rev_temp <- data.frame(Review = review,
                               Time = time,
                               Product = rep(name))
        datt <- rbind(datt,rev_temp)
      }
    }else{
      # get review from all review pages if there are more than 6 review
      for(j in 1:rev){
        # review text
        reviewx <- rmdr$findElements("css",".shopee-product-rating__content")
        review <- unlist(lapply(reviewx,function(x) x$getElementText()))
        # review time
        timex <- rmdr$findElements("css",".shopee-product-rating__time")
        time <- unlist(lapply(timex,function(x) x$getElementText()))

        rev_temp <- data.frame(Review = review,
                               Time = time,
                               Product = rep(name))
        datt <- rbind(datt,rev_temp)

        # next review button
        rmdr$findElement("css",".shopee-icon-button--right")$clickElement()
        Sys.sleep(3)
      }
    }
    # append all product review to list
    review_product[[i]] <- datt

  }
}

There’s a chance you can’t extract the data in one go. You can save recent data and bind it to newest data using rbind.

#desc_product_full <- data.frame()

desc_product_full <- rbind(desc_product_full,desc_product)
saveRDS(desc_product_full,"details.rds")

Return the review to dataframe based on its id

temp_nonmul <- bind_rows(review_product,.id = "id")

#new_nonmul_rev <- data.frame()
#new_nonmul_rev <- rbind(new_nonmul_rev,temp_nonmul)
saveRDS(new_nonmul_rev,"review_1.rds")

load saved data for publication purposes

desc_product_full <- readRDS("data_input/Rselenium-intro/details.rds")
new_nonmul_rev <- readRDS("data_input/Rselenium-intro/review_1.rds")

product details

head(desc_product_full)
#>                                                                                     Name
#> 1                        iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 2                         iphone X 64gb second fullset Normal Ex Inter free asuransi JNE
#> 3                      iPhone X 256Gb second fullset normal no face id free asuransi JNE
#> 4 iPhone X 256GB 64GB Second Fulset MULUS EX Inter Ori Battery 2 7 8 6 mAh Silver - Gray
#> 5               iphone x 256gb second fullset ex inter NO FACE ID JNE INSURANCE INCLUDES
#> 6           [ TERMURAH ] APPLE IPHONE X SECOND 64GB 256GB GREY / SILVER ORIGINAL GARANSI
#>   Rating                     Price Sold
#> 1    4.7 Rp7.098.000 - Rp8.098.000  334
#> 2    4.7 Rp6.898.000 - Rp7.498.000  547
#> 3    4.6               Rp7.298.000   25
#> 4    4.4 Rp6.995.000 - Rp7.225.000  349
#> 5    5.0               Rp7.295.000    3
#> 6    4.9 Rp7.985.000 - Rp9.285.000  353
#>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       desc
#> 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nMohon diperhatikan, lapak kami jual hp 3 macam, yakni :\na) mulus dengan kemulusan 98-99% (BISA SEMUA KARTU)\nb) HANYA BISA KARTU SMARTFREN dan INDOSAT\nc) KONDISI LECET DIKIT (wajib minta foto kondisi hp untuk lebih yakin, karena kami tdk akan menerima komplen kondisi hp lecet)\n\nKONDISI PRODUK :\n* SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n* ALL UNIT FU (factory unlock mendukung semua sim card GSM Indonesia )\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR.\n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nKami menjual iphone X 64GB dengan 2 kondisi :\n1) SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n2) HANYA BISA KARTU SMARTFREN dan INDOSAT (warna SILVER, GREY tulis di catatan untuk warna yg diinginkan)\n\nKONDISI PRODUK :\n* ALL UNIT MULUS 98-99%\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR. \n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nKONDISI PRODUK :\n* ALL UNIT MULUS 98-99%\n* SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n* no face id ( yang rusak hanya FACE ID, fungsi lainnya aman )\n* LCD  ORIGINAL, BUKAN REKON/ REFURBISH\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nkalo agan mau yg mulus dan fungsi normal klik link ini gan https://shopee.co.id/product/47745953/2055161396?v=47e&smtt=0.0.3\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR.\n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 4                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Selamat datang di Kino Phone Cell  \n\n*Menyediakan HP Second Original Bergaransi dgn harga dan kualitas terbaik\n*Profesional Telah Berjualan Sejak Tahun 2008 & Online Shop Sejak 2015\n*Tingkat Kepuasan & Reputasi Toko di atas Rata – Rata Seller lainya\n\nVery Wellcome Reseller , Stok Toko & Dropshiper Akan dikirim tanpa nota harga asli untuk menjalin hubungan kerja sama yg baik\n\nReady Stok Selama iklan Aktif (Warna dan Kapasitas Memory Sesuaikan pada Judul dan Variant)\ndan Wajib Cantumkan Catatan Pembelian Saat Check Out\n\n*** BACA INI SEBELUM MEMBELI ****\n- Produk Original Bekas Garansi Internasional\n- Mulus 97%-99% (like New)\n- Batre Healt Sehat dan Normal (tidak bisa request BH)\n- LCD dan Casing original pabrik\n- 100% BISA Semua SIM Operator INDO\n- Icloud Aman , Bebas Reset & Update\n- Imei BOX dan mesin COCOK 100%\n- Garansi HP 3 Hari Sejak Diterima\n- Kondisi Second Tidak Sama Setiap Saat tp dikirim yg terbaik \n- Kelengkapan Aksesoris OEM Artinya Bukan Original Bawaan Pabrik \n- (Dus Box + Imei , Kabel + Adaptor Charger , Headset)\n- Headset Iphone Koneksi “Bluetooth Pairing \n\nKami Tentu Akan Quality Check Sebelum Mengirimkan Pesanan\n\nTerimakasih Sudah Percayakan Toko Kami \nMampir Trs ke Toko kami \n-TK : Kino Phone Cell\n-BK : VIP Cellular\n-SH : KPC VIP Cellular\n\ninfo & saran : \nmohon dicek dulu keseluruhan fungsi sebelum selesaikan pesanan \njika ada keluhan silahkan klik ajukan pengembalian barang untuk proses retur makasih <U+0001F64F>\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!\n\nDapatkan Kualitas hanya di Toko kami iG & YT : KPC VIP Cellular
#> 5                                                                                                                                                                                                                         Bosen karena hp masi itu itu aja ? Atau uda rusak tapi belum bisa kebeli yang baru? Ke iphone shopping aja... kami jual hp dengan harga murah kualitas mewah....\n\nKenapa harus belanja di sini?? \n1) Produk yang kami jual apple ori bukan replika\n2) Kualitas mewah harga murah \n3) Kami sebagai penjual memberi pelayanan yang baik untuk konsumen\n4) Hari minggu atau tanggal merah selalu ada pengiriman \n\nSebelum klik beli wajib baca yang ada dibawah ini dulu ya gan : \n1) SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n2) Kondisi no face id ( Fungsi face id tidak bisa digunakan, fungsi lainnya aman)\n3) Semua produk yang kami jual bekas garansi internasional \n4) Semua produk yang kami jual kondisi kemulusan 98-99%\n5) Semua produk yg kami jual kondisi icloud kosong (langsung masukkin id apple agan aja)\n6) Kelengkapan produk fullset oem (tapi utk acc tdk ada garansi ya gan). Untuk warna dus yang kami kirim diusahakan sesuai dengan warna hp yg diorder. Tapi apabila kami kirim dengan warna dus yg tdk sesuai harap dimaklumi karena stok kami habis.\n7) Sebelum pengiriman kami selalu melakukan pengecekan pada fungsi hp yg akan dikirim (QC)\n8) pastikan segel masi utuh dan tdk rusak ataupun hilang)\n9) Mohon maaf untuk battrey health tidak bisa request karena stok kami random, akan tetapi jika agan tulis dinote kami usahakan kirim sesuai tapi jika tdk kami kirim sesuai stok dan tidak service (BH 80++%)\n\nGaransi dari toko kami bisa hangus jika kesalahan pengguna / human error seperti : \nTerjatuh\nTerkena cairan\nTerbakar\nSegel pada hp rusak/hilang\n\nSyarat dan ketentuan retur :\n+ Kami tidak akan proses retur jika masi ada icloud di hp \n+ Barang saat diretur harus sama seperti waktu kami kirim (segel harus utuh)\n+ Ongkos kirim dan retur sepenuhnya ditanggung oleh pembeli \n+ Review atau komen negatif pada lapak kami garansi hangus
#> 6 PALING REKOMEND \n\niPhone X 64 dan 256GB Second Original Fullset\n\nMohon dibaca baik yaa, Kondisi :\n\n--Fisik mulus 95-97%\n-- BISA SEMUA OPERATOR\n\n--Ready Silver dan Grey \n— Dijami LCD Original 100% smooth bukan KW\n-- Second Original bukan Rekondisi, apalagi Rakitan\n— True Tone aktif\n--Kondisi Normal \n-- Face ID On\n--Touchscreen smooth namanya juga masih original\n--Icloud Kosong \n--Ex Garansi Apple Store International\n--Battere Health rata" diatas 83%  normal\n\nTIDAK BISA REQ BH YA KAKAKU, batre original bukan gantian, wajar kalau tidak 100% namanya juga hp second <U+0001F60A>\n-- Sinyal aman, karena sudah diregister Operator Indonesia\n\nSekali lg ya tidak bisa REQUEST BH SEGINI SEGINI, taro aja di notes, kalau beruntung kalian dapat yg dimau, kalau tidak kami tetep kiriim sesuai stok dan sesuai iklan.\n\nTidak jual janji janji, kondisi sesuai deskripsi, mohon di baca.\n\nKalau maksa bgt mau BH yg perfect solusi nya cuma satu kakaku <U+27A1><U+FE0F><U+27A1><U+FE0F><U+27A1><U+FE0F>BELI BARU<U+2B05><U+FE0F><U+2B05><U+FE0F><U+2B05><U+FE0F>\n\nKelengkapan yang didapat: \nAksesoris Oem ( Tanpa kabel converting ) isi nya: \n--Charger Iphone \n--Kabel Data \n--Dusbook \n--Buku2 Lengkap\n--Handsfree\n\n=============================================================\nGARANSI BERLAKU SELAMA 07 HARI\nDengan Syarat :\n1. Kerusakan Murni dari Kami, Bukan dari Pembeli\n2. Segel Toko yang Tertempel Dari Kami Masih Seperti Pada Saat Diterima\n3. Handphone Dalam Kondisi Semula Pada Saat Diterima\n4. Jika Tidak Sesuai Dengan Kondisi Di Atas, Hangus Masa Garansi\n5. Ongkos Kirim Retur/Refund sepenuhnya ditanggung oleh pembeli\n\nGARANSI TIDAK BERLAKU JIKA DI TEMUKAN HUMAN EROR,SEPERTI :\n- TERKENA CAIRAN\n- SEGEL RUSAK/HILANG\n- TERBAKAR\n- TERJATUH\n- HUMAN EROR (KESALAHAN PENGGUNA)\n- UPDATE IOS/OS SENDIRI OLEH PEMBELI\n\nBaca baik baik deskripsi yang sudah di buat, apabila complain padahal sudah di jelaskan di deskripsi maka garansi hangus :) \n\n\n\n#iphone #iphonex #iphonegrey #iphoneoriginal #iphonesingapore #iphonesecond #iphonexgrey
#>                                                                                                                              Link
#> 1                      https://shopee.co.id/iPhone-X-256gb-Second-Normal-Fullset-Ex-Inter-free-asuransi-JNE-i.47745953.2055161396
#> 2                       https://shopee.co.id/iphone-X-64gb-second-fullset-Normal-Ex-Inter-free-asuransi-JNE-i.47745953.1887735183
#> 3                    https://shopee.co.id/iPhone-X-256Gb-second-fullset-normal-no-face-id-free-asuransi-JNE-i.47745953.5510545590
#> 4 https://shopee.co.id/iPhone-X-256GB-64GB-Second-Fulset-MULUS-EX-Inter-Ori-Battery-2-7-8-6-mAh-Silver-Gray-i.61376437.4312219803
#> 5             https://shopee.co.id/iphone-x-256gb-second-fullset-ex-inter-NO-FACE-ID-JNE-INSURANCE-INCLUDES-i.73370096.7705786775
#> 6              https://shopee.co.id/-TERMURAH-APPLE-IPHONE-X-SECOND-64GB-256GB-GREY-SILVER-ORIGINAL-GARANSI-i.10230608.1586990183

product review

head(new_nonmul_rev)
#>   id
#> 1  1
#> 2  1
#> 3  1
#> 4  1
#> 5  1
#> 6  1
#>                                                                                                                                                                                                                                                                                                           Review
#> 1                                                                                                                                                                                                          good good good good good good good good good good good good good good good good good good good good  
#> 2                     Wowwww paket sudah datang.. Pertama kali order, mantap kali nih barang bener" mulus.. Alhamdulillah dpet HB 100% dong.. Bener" amanah nih..\nThanks kak <U+0001F60D><U+0001F60D><U+0001F60D><U+0001F60D> bener" suka banget.. Mudah"an awet ya .. Sukses trus kak <U+0001F607><U+0001F607>
#> 3                                                                                                        Untuk orderan kali ini saya kasih 4 bintang , soalnya saya dapat HB 85 % bukan 90++%. Kalo untuk yg lain masih aman dan memuaskan.\nSemoga untuk orderan ke 3 nanti memuaskan seperti orderan pertama. 
#> 4             Maaf baru buat penilaian, karna saya mau tes dulu.\nHp nya mulus banget si luarnya, hb dapet yg 86% ya gapapa tapi pas baru beberapa hari saya cek lagi hp berubah jadi servis dan hp juga cepet banget panas nya padahal pemakaian normal<U+0001F614>\nTapi gapapa namanya juga BEKAS<U+0001F44C>
#> 5                                                                                                                                                                                 iPhonenya sangatt sangatt memuaskan sekali... req BH 90+.. eehh datengnya dlm kondisi 100%... mantapp <U+0001F44D><U+0001F44D>
#> 6 Alhamdulillah paket sampai dengan baik, gak ada 24 jam paket sampai. Adminnya ramah, baik, fast respon juga, fast pengemasan dan pengiriman.\nUntuk unit iphonenya cuman minta dikasih yg terbaik aja, alhamdulillah iphone seken rasa baruuuuu hehe. 3utools hijau semua... \nTerima kasih kak sukses selalu.
#>               Time
#> 1 2020-11-19 20:48
#> 2 2020-10-29 09:16
#> 3 2020-10-31 13:04
#> 4 2020-10-13 21:46
#> 5 2020-10-10 06:59
#> 6 2020-08-31 12:26
#>                                                           Product
#> 1 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 2 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 3 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 4 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 5 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 6 iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE

Data Analysis

Now we have the data, next you can do whatever you want to analyze the data. Here I provide some example in analyzing review data such as: analyzing trend, best product/store, and sentiment analysis

Wrangling

desc_clean <- desc_product_full %>% 
  mutate(Rating = ifelse(str_detect(Rating,"none"),0,Rating)) %>% 
  mutate(Rating = as.numeric(Rating),
         Sold = as.numeric(Sold),
         Price = str_remove(Price,"^.*-"),
         Price = str_remove_all(Price,"\\D+"),
         Price = as.numeric(Price)) %>% 
  filter(Price > 5000000)
  
head(desc_clean)
#>                                                                                     Name
#> 1                        iPhone X 256gb Second Normal Fullset Ex Inter free asuransi JNE
#> 2                         iphone X 64gb second fullset Normal Ex Inter free asuransi JNE
#> 3                      iPhone X 256Gb second fullset normal no face id free asuransi JNE
#> 4 iPhone X 256GB 64GB Second Fulset MULUS EX Inter Ori Battery 2 7 8 6 mAh Silver - Gray
#> 5               iphone x 256gb second fullset ex inter NO FACE ID JNE INSURANCE INCLUDES
#> 6           [ TERMURAH ] APPLE IPHONE X SECOND 64GB 256GB GREY / SILVER ORIGINAL GARANSI
#>   Rating   Price Sold
#> 1    4.7 8098000  334
#> 2    4.7 7498000  547
#> 3    4.6 7298000   25
#> 4    4.4 7225000  349
#> 5    5.0 7295000    3
#> 6    4.9 9285000  353
#>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       desc
#> 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nMohon diperhatikan, lapak kami jual hp 3 macam, yakni :\na) mulus dengan kemulusan 98-99% (BISA SEMUA KARTU)\nb) HANYA BISA KARTU SMARTFREN dan INDOSAT\nc) KONDISI LECET DIKIT (wajib minta foto kondisi hp untuk lebih yakin, karena kami tdk akan menerima komplen kondisi hp lecet)\n\nKONDISI PRODUK :\n* SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n* ALL UNIT FU (factory unlock mendukung semua sim card GSM Indonesia )\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR.\n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nKami menjual iphone X 64GB dengan 2 kondisi :\n1) SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n2) HANYA BISA KARTU SMARTFREN dan INDOSAT (warna SILVER, GREY tulis di catatan untuk warna yg diinginkan)\n\nKONDISI PRODUK :\n* ALL UNIT MULUS 98-99%\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR. \n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Mengapa harus belanja di Excelappleshop :\n* Trusted seller (bukan cuma seller musiman yg setelah barang jualannya laku menghilang entah kemana)\n* Hari Minggu dan tanggal merah lainnya PENGIRIMAN tetap ON\n* Penginputan resi dihari berikutnya\n\nKONDISI PRODUK :\n* ALL UNIT MULUS 98-99%\n* SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n* no face id ( yang rusak hanya FACE ID, fungsi lainnya aman )\n* LCD  ORIGINAL, BUKAN REKON/ REFURBISH\n* ALL UNIT ICLOUD AMAN \n* ALL UNIT FULLSET KOMPLIT OEM ( TIDAK ADA GARANSI UNTUK ACC ). HARAP MAKLUM JIKA WARNA DUS YANG DIKIRIM RANDOM KARENA STOK HABIS. TAPI KAMI USAHAKAN SESUAI DENGAN WARNA HP\n* TIDAK BISA REQUEST BATRE HEALTH SEGINI SEGINI . SILAHKAN TULIS DICATATAN, KALAU BERUNTUNG KALIAN DAPAT YANG DIMAU. JIKA TIDAK KAMI TETAP KIRIM  SESUAI STOK DAN TIDAK SERVICE (BH 80++)\n\nkalo agan mau yg mulus dan fungsi normal klik link ini gan https://shopee.co.id/product/47745953/2055161396?v=47e&smtt=0.0.3\n\nGaransi tidak berlaku jika human error (kesalahan pengguna) seperti :\n- terkena cairan \n- segel rusak/hilang\n- terbakar \n- terjatuh\n\nKETENTUAN RETUR BARANG :\n1) GARANSI HANYA BERLAKU JIKA SEGEL MASIH UTUH DAN NON HUMAN ERROR.\n2) KAMI TIDAK AKAN PROSES RETUR APABILA ADA ICLOUD DI HP TERSEBUT \n3) ONGKOS KIRIM DAN RETUR SEPENUHNYA DITANGGUNG OLEH PEMBELI \n4) BARANG SAAT DIRETUR HARUS SEPERTI WAKTU KAMI KIRIM DAN SEGEL UTUH \n\nNB : \n- MOHON DIBACA TERLEBIH DAHULU SEBELUM MELAKUKAN TRANSAKSI\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!
#> 4                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Selamat datang di Kino Phone Cell  \n\n*Menyediakan HP Second Original Bergaransi dgn harga dan kualitas terbaik\n*Profesional Telah Berjualan Sejak Tahun 2008 & Online Shop Sejak 2015\n*Tingkat Kepuasan & Reputasi Toko di atas Rata – Rata Seller lainya\n\nVery Wellcome Reseller , Stok Toko & Dropshiper Akan dikirim tanpa nota harga asli untuk menjalin hubungan kerja sama yg baik\n\nReady Stok Selama iklan Aktif (Warna dan Kapasitas Memory Sesuaikan pada Judul dan Variant)\ndan Wajib Cantumkan Catatan Pembelian Saat Check Out\n\n*** BACA INI SEBELUM MEMBELI ****\n- Produk Original Bekas Garansi Internasional\n- Mulus 97%-99% (like New)\n- Batre Healt Sehat dan Normal (tidak bisa request BH)\n- LCD dan Casing original pabrik\n- 100% BISA Semua SIM Operator INDO\n- Icloud Aman , Bebas Reset & Update\n- Imei BOX dan mesin COCOK 100%\n- Garansi HP 3 Hari Sejak Diterima\n- Kondisi Second Tidak Sama Setiap Saat tp dikirim yg terbaik \n- Kelengkapan Aksesoris OEM Artinya Bukan Original Bawaan Pabrik \n- (Dus Box + Imei , Kabel + Adaptor Charger , Headset)\n- Headset Iphone Koneksi “Bluetooth Pairing \n\nKami Tentu Akan Quality Check Sebelum Mengirimkan Pesanan\n\nTerimakasih Sudah Percayakan Toko Kami \nMampir Trs ke Toko kami \n-TK : Kino Phone Cell\n-BK : VIP Cellular\n-SH : KPC VIP Cellular\n\ninfo & saran : \nmohon dicek dulu keseluruhan fungsi sebelum selesaikan pesanan \njika ada keluhan silahkan klik ajukan pengembalian barang untuk proses retur makasih <U+0001F64F>\n- REVIEW / COMMENT NEGATIF PADA LAPAK GARANSI VOID / HANGUS!!!\n\nDapatkan Kualitas hanya di Toko kami iG & YT : KPC VIP Cellular
#> 5                                                                                                                                                                                                                         Bosen karena hp masi itu itu aja ? Atau uda rusak tapi belum bisa kebeli yang baru? Ke iphone shopping aja... kami jual hp dengan harga murah kualitas mewah....\n\nKenapa harus belanja di sini?? \n1) Produk yang kami jual apple ori bukan replika\n2) Kualitas mewah harga murah \n3) Kami sebagai penjual memberi pelayanan yang baik untuk konsumen\n4) Hari minggu atau tanggal merah selalu ada pengiriman \n\nSebelum klik beli wajib baca yang ada dibawah ini dulu ya gan : \n1) SINYAL TIDAK TERBLOKIR (BISA SMUA KARTU)\n2) Kondisi no face id ( Fungsi face id tidak bisa digunakan, fungsi lainnya aman)\n3) Semua produk yang kami jual bekas garansi internasional \n4) Semua produk yang kami jual kondisi kemulusan 98-99%\n5) Semua produk yg kami jual kondisi icloud kosong (langsung masukkin id apple agan aja)\n6) Kelengkapan produk fullset oem (tapi utk acc tdk ada garansi ya gan). Untuk warna dus yang kami kirim diusahakan sesuai dengan warna hp yg diorder. Tapi apabila kami kirim dengan warna dus yg tdk sesuai harap dimaklumi karena stok kami habis.\n7) Sebelum pengiriman kami selalu melakukan pengecekan pada fungsi hp yg akan dikirim (QC)\n8) pastikan segel masi utuh dan tdk rusak ataupun hilang)\n9) Mohon maaf untuk battrey health tidak bisa request karena stok kami random, akan tetapi jika agan tulis dinote kami usahakan kirim sesuai tapi jika tdk kami kirim sesuai stok dan tidak service (BH 80++%)\n\nGaransi dari toko kami bisa hangus jika kesalahan pengguna / human error seperti : \nTerjatuh\nTerkena cairan\nTerbakar\nSegel pada hp rusak/hilang\n\nSyarat dan ketentuan retur :\n+ Kami tidak akan proses retur jika masi ada icloud di hp \n+ Barang saat diretur harus sama seperti waktu kami kirim (segel harus utuh)\n+ Ongkos kirim dan retur sepenuhnya ditanggung oleh pembeli \n+ Review atau komen negatif pada lapak kami garansi hangus
#> 6 PALING REKOMEND \n\niPhone X 64 dan 256GB Second Original Fullset\n\nMohon dibaca baik yaa, Kondisi :\n\n--Fisik mulus 95-97%\n-- BISA SEMUA OPERATOR\n\n--Ready Silver dan Grey \n— Dijami LCD Original 100% smooth bukan KW\n-- Second Original bukan Rekondisi, apalagi Rakitan\n— True Tone aktif\n--Kondisi Normal \n-- Face ID On\n--Touchscreen smooth namanya juga masih original\n--Icloud Kosong \n--Ex Garansi Apple Store International\n--Battere Health rata" diatas 83%  normal\n\nTIDAK BISA REQ BH YA KAKAKU, batre original bukan gantian, wajar kalau tidak 100% namanya juga hp second <U+0001F60A>\n-- Sinyal aman, karena sudah diregister Operator Indonesia\n\nSekali lg ya tidak bisa REQUEST BH SEGINI SEGINI, taro aja di notes, kalau beruntung kalian dapat yg dimau, kalau tidak kami tetep kiriim sesuai stok dan sesuai iklan.\n\nTidak jual janji janji, kondisi sesuai deskripsi, mohon di baca.\n\nKalau maksa bgt mau BH yg perfect solusi nya cuma satu kakaku <U+27A1><U+FE0F><U+27A1><U+FE0F><U+27A1><U+FE0F>BELI BARU<U+2B05><U+FE0F><U+2B05><U+FE0F><U+2B05><U+FE0F>\n\nKelengkapan yang didapat: \nAksesoris Oem ( Tanpa kabel converting ) isi nya: \n--Charger Iphone \n--Kabel Data \n--Dusbook \n--Buku2 Lengkap\n--Handsfree\n\n=============================================================\nGARANSI BERLAKU SELAMA 07 HARI\nDengan Syarat :\n1. Kerusakan Murni dari Kami, Bukan dari Pembeli\n2. Segel Toko yang Tertempel Dari Kami Masih Seperti Pada Saat Diterima\n3. Handphone Dalam Kondisi Semula Pada Saat Diterima\n4. Jika Tidak Sesuai Dengan Kondisi Di Atas, Hangus Masa Garansi\n5. Ongkos Kirim Retur/Refund sepenuhnya ditanggung oleh pembeli\n\nGARANSI TIDAK BERLAKU JIKA DI TEMUKAN HUMAN EROR,SEPERTI :\n- TERKENA CAIRAN\n- SEGEL RUSAK/HILANG\n- TERBAKAR\n- TERJATUH\n- HUMAN EROR (KESALAHAN PENGGUNA)\n- UPDATE IOS/OS SENDIRI OLEH PEMBELI\n\nBaca baik baik deskripsi yang sudah di buat, apabila complain padahal sudah di jelaskan di deskripsi maka garansi hangus :) \n\n\n\n#iphone #iphonex #iphonegrey #iphoneoriginal #iphonesingapore #iphonesecond #iphonexgrey
#>                                                                                                                              Link
#> 1                      https://shopee.co.id/iPhone-X-256gb-Second-Normal-Fullset-Ex-Inter-free-asuransi-JNE-i.47745953.2055161396
#> 2                       https://shopee.co.id/iphone-X-64gb-second-fullset-Normal-Ex-Inter-free-asuransi-JNE-i.47745953.1887735183
#> 3                    https://shopee.co.id/iPhone-X-256Gb-second-fullset-normal-no-face-id-free-asuransi-JNE-i.47745953.5510545590
#> 4 https://shopee.co.id/iPhone-X-256GB-64GB-Second-Fulset-MULUS-EX-Inter-Ori-Battery-2-7-8-6-mAh-Silver-Gray-i.61376437.4312219803
#> 5             https://shopee.co.id/iphone-x-256gb-second-fullset-ex-inter-NO-FACE-ID-JNE-INSURANCE-INCLUDES-i.73370096.7705786775
#> 6              https://shopee.co.id/-TERMURAH-APPLE-IPHONE-X-SECOND-64GB-256GB-GREY-SILVER-ORIGINAL-GARANSI-i.10230608.1586990183
library(lubridate)
library(ggplot2)

plot_trend <- new_nonmul_rev %>% 
  filter(Product %in% unique(desc_clean$Name)) %>% 
  mutate(date = date(ymd_hm(Time))) %>% 
  group_by(date) %>% 
  summarise(phone_sold = n()) %>% 
  mutate(month = month(date,label = T),
         year = year(date)) %>% 
  group_by(month,year) %>% 
  mutate(ismax = max(phone_sold),
         ismax = ifelse(phone_sold==ismax,T,F)) %>% 
  ggplot(aes(x = date, y = phone_sold)) +
  geom_line(aes(group = 1)) +
  geom_point(aes(col = ismax),show.legend = F) +
  geom_smooth(col = "#e02509",method = "loess") +
  scale_color_manual(values = c("black","#e02509")) +
  labs(title = "Iphone X Buying Trend",
       x = "Date",y = "Phone Sold") +
  theme_minimal()

plot_trend

Products sold most consistently

most_product <- new_nonmul_rev %>% 
  filter(Product %in% unique(desc_clean$Name)) %>% 
  mutate(date = date(ymd_hm(Time))) %>% 
  group_by(Product) %>% 
  summarise(f = n()) %>% 
  arrange(-f) %>% 
  head(6) %>% 
  pull(Product)

new_nonmul_rev %>% 
  filter(Product %in% most_product) %>% 
  mutate(date = date(ymd_hm(Time))) %>% 
  group_by(date,Product) %>% 
  summarise(freq = n()) %>% 
  arrange() %>% 
  # padr::pad(start_val = as.Date("2019-10-01"),end_val = as.Date("2020-11-23"),
  #           group = "Product",interval = "day") %>% 
  # mutate(freq = replace_na(freq,0)) %>% 
  ggplot(aes(x = date, y = freq,group = Product, col = Product)) +
  geom_line() + geom_point() +
  scale_x_date(date_labels = "%b-%y") + 
  theme_minimal() +
  facet_wrap(~Product,scales = "free_x") +
  labs(title = "Highest Selling Product Trend",
       x = "", y = "Frequency") +
  theme(legend.position = "none",
        strip.background = element_rect(fill = "#781212"),
        strip.text.x = element_text(colour = "white"))

Best product with highest positive sentiment

library(textclean)
library(stringr)
library(katadasaR)
library(tm)
library(SnowballC)

# slang word indo
indo_stem <- read.csv("data_input/Rselenium-intro/colloquial-indonesian-lexicon.csv")

# add custom bahasa stopwords
bahasa.sw <- read.csv("data_input/Rselenium-intro/Bahasa.stopwords.csv", header = F,fileEncoding = "UTF-8-BOM")
bahasa.sw <- as.character(bahasa.sw$V1)
bahasa.sw <- c(bahasa.sw, stopwords())

# senti-strength bahasa score
bahasa.sentiment <- read.delim("data_input/Rselenium-intro/sentiwords_id.txt",sep = ":",header = F)
bahasa.sentiment <- bahasa.sentiment %>% setNames(c("words","weight")) %>% 
  mutate(words = str_trim(words))

text cleaner

# stemming function using package katadasaR
stemming_bahasa <- function(x){
  paste(lapply(x,katadasar),collapse = " ")
}

# function textcleaner
textcleaner <- function(x){
  x <- as.character(x)
  
  x <- x %>%
    str_to_lower() %>%  # convert all the string to low alphabet
    replace_contraction() %>% # replace contraction to their multi-word forms
    replace_internet_slang() %>% # replace internet slang to normal words
    replace_emoji() %>% # replace emoji to words
    replace_emoticon() %>% # replace emoticon to words
    replace_hash(replacement = "") %>% # remove hashtag
    replace_word_elongation() %>% # replace informal writing with known semantic replacements
    replace_internet_slang(slang = paste0("\\b",
                                          indo_stem$slang,"\\b"),
                           replacement = indo_stem$formal,ignore.case = T) %>%  # bahasa slang word
    lapply(stemming_bahasa) %>% # bahasa stemming
    replace_number(remove = T) %>% # remove number
    replace_date(replacement = "") %>% # remove date
    replace_time(replacement = "") %>% # remove time
    str_replace_all(pattern = "[[:punct:]]",replacement = " ") %>% # remove punctuation
    str_replace_all(pattern = "[^\\s]*[0-9][^\\s]*",replacement = " ") %>% # remove mixed string n number
    removeWords(bahasa.sw) %>% # apply bahasa stopwords
    str_squish() %>% # reduces repeated whitespace inside a string.
    str_trim() # removes whitespace from start and end of string
  
  return(as.data.frame(x))
}
review_filter <- new_nonmul_rev %>% 
  filter(Product %in% unique(desc_clean$Name))

clean_review <- textcleaner(review_filter$Review)
clean_review <- readRDS("data_input/Rselenium-intro/review_clean.rds")
head(clean_review)
#>                                                                                                                                                                                                                                                                                x
#> 1                                                                                                                                                                            good good good good good good good good good good good good good good good good good good good good
#> 2 wow paket kali order mantap kali nih barang mulus alhamdulillah dpet hb amanah nih thanks kak smiling face heart eyes smiling face heart eyes smiling face heart eyes smiling face heart eyes suka banget mudah mudahan awet ya sukses kak smiling face halo smiling face halo
#> 3                                                                                                                                                                                             orderan kali kasih bintang hb kalo aman memuaskan semoga orderan memuaskan orderan
#> 4                                                                                                         maaf penilaian tes hp mulus banget sih luarnya hb ya gapapa pas cek hp berubah servis hp cepat banget panas pemakaian normal pensive face gapapa namanya bekas OK hand
#> 5                                                                                                                                                                                         iphonenya sangatt sangatt memuaskan req bh eehh datengnya kondisi mantap thumbs thumbs
#> 6                                                                                         alhamdulillah paket jam paket adminnya ramah fast respon fast pengemasan pengiriman unit iphonenya cuman dikasih terbaik alhamdulillah iphone seken hehe hijau terima kasih kak sukses
# function sentiment scoring
sentiment_matching <- function(x){
  x <- str_split(x,"\\s+") %>%                    # seperate the words from sentence
    unlist()
  x <- match(x,bahasa.sentiment$words)            # match seperated words to bahasa.sentiment words
  bin <- matrix(ncol = 1,nrow = length(x))        # create empty matrix to collect the score from each review
  for(i in seq_along(x)){                         # build loop function to apply the match function to every rows
    if(is.na(x[i] == T)){
      bin[i] <- 0}else{
        bin[i] <- bahasa.sentiment$weight[x[i]]   # match the score by its weight
      }
  }
  return(as.numeric(sum(bin)))                    # sum the score from each row and return as numeric value
}

clean_review <- clean_review %>% 
  rowwise() %>% 
  mutate(score = sentiment_matching(x)) %>%
  mutate(sentiment = ifelse(score <= 0,"negative","positive"))
clean_review <- readRDS("data_input/Rselenium-intro/sent_review.rds")
review_sen <- new_nonmul_rev %>% 
  filter(Product %in% unique(desc_clean$Name)) %>% 
  mutate(score = clean_review$score,
         sentiment = clean_review$sentiment)

plot_sentiment <- table(review_sen$Product,review_sen$sentiment) %>% data.frame() %>% 
  setNames(c("Product","sentiment","freq")) %>% 
  filter(sentiment == "positive") %>% 
  arrange(-freq) %>% 
  mutate(text = paste(Product,"\n positive:",freq)) %>% 
  head(10) %>% 
  ggplot(aes(x = reorder(Product,freq), y= freq, fill = freq,text=text)) + 
  geom_col() +
  labs(title = "Product with highest sentiment review",x = "Product", y = "Freq") +
  theme_minimal() +
  scale_x_discrete(label = NULL) +
  theme(legend.position = "none")

library(plotly)
ggplotly(plot_sentiment,tooltip = "text")


Scroll to Top