Managing PSD kel 3

Angga Fathan Rofiqy

2023-09-20

I. Setting

Function biar gak perlu ganti backslash (\) jadi slash (/).

path <- function() gsub  ( "\\\\",  "/",  readClipboard ()  )
#Copy path, Panggil function di console
#Copy r path, paste ke var yang diinginkan

Set Working Directory

Function biar gak perlu repot buat install("") atau load() package.

#                      -=( Install & Load Package Function )=-
install_load <- function (package1, ...)  {   

   # convert arguments to vector
   packages <- c(package1, ...)

   # start loop to determine if each package is installed
   for(package in packages){

       # if package is installed locally, load
       if(package %in% rownames(installed.packages()))
          do.call('library', list(package))

       # if package is not installed locally, download, then load
       else {
          install.packages(package)
          do.call("library", list(package))
       }
   } 
}

Function position_stack_and_nudge

#                          -=( GGPLOT POSITION FUNCTION )=-
library(ggplot2)
position_stack_and_nudge <- function(x = 0, y = 0, vjust = 1, reverse = FALSE) {
  ggproto(NULL, PositionStackAndNudge,
    x = x,
    y = y,
    vjust = vjust,
    reverse = reverse
  )
}

#' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @noRd
PositionStackAndNudge <- ggproto("PositionStackAndNudge", PositionStack,
  x = 0,
  y = 0,

  setup_params = function(self, data) {
    c(
        list(x = self$x, y = self$y),
        ggproto_parent(PositionStack, self)$setup_params(data)
    )
  },

  compute_layer = function(self, data, params, panel) {
    # operate on the stacked positions (updated in August 2020)
    data = ggproto_parent(PositionStack, self)$compute_layer(data, params, panel)

    x_orig <- data$x
    y_orig <- data$y
    # transform only the dimensions for which non-zero nudging is requested
    if (any(params$x != 0)) {
      if (any(params$y != 0)) {
        data <- transform_position(data, function(x) x + params$x, function(y) y + params$y)
      } else {
        data <- transform_position(data, function(x) x + params$x, NULL)
      }
    } else if (any(params$y != 0)) {
      data <- transform_position(data, function(x) x, function(y) y + params$y)
    }
    data$nudge_x <- data$x
    data$nudge_y <- data$y
    data$x <- x_orig
    data$y <- y_orig

    data
  },

  compute_panel = function(self, data, params, scales) {
      ggproto_parent(PositionStack, self)$compute_panel(data, params, scales)
  }
)

Theme Pie Chart.

install_load('ggrepel')
#                             -=( Label Pie Chart )=-
lab.p <- list(
  geom_label_repel( aes(label = paste0(perc,"(",n,")")),
          position = position_stack_and_nudge(vjust = 0.5, x = 0.65),
          direction='y', fontface = 'bold', color = 'white',
          box.padding = unit(0.35, "lines"),
          point.padding = unit(0.5, "lines"), segment.color = '#454545',
          size=10) 
)
#                           -=( THEME Pie Chart )=-
theme.p <- list(
  theme_void()  , 
        theme(
        text = element_text(size = 36),
        axis.text.y = element_text(vjust = .5, face = "bold"),
        plot.title = element_text(hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5) )
)

Function Pie Chart

#                           -=( Pie Chart FUNCTION )=-
plot.p <- function(dt, title = "Pice Chart"){
  install_load("ggplot2", "dplyr", "viridis", "ggrepel", "tidyverse",'scales')
  #DATA FRAME
  df <- data.frame(ket = dt) %>%
    #Frequency
    group_by(ket) %>%
    count() %>%
    ungroup() %>%
    mutate(perc = percent(n/sum(n), accuracy = 0.1, trim = FALSE))
  
  #PIE CHART
  sp <- ggplot(data=df, aes(x = "", y = n, fill = ket)) +
          geom_col(width = 1, color = "white", linewidth = 2,
                   position = position_stack()) +
        coord_polar(theta = "y") +
        scale_alpha_manual(values = c("0"=0, "1"=1, "2"=0.7), guide=F) +
        scale_x_discrete(breaks = NULL) +
        scale_y_continuous(breaks = NULL) +
        labs(title = title) + #Title
        #COLORING
        scale_fill_viridis(alpha = 0.75, #Opacity
                           begin = 0.2, #Color pallte scale begins
                           end = 0.5, #Color pallte scale ends
                           direction = -1, #Flip color scale
                           discrete = T, #Discrete Value
                           option = "D") + #Color Palette
        theme.p + #Theme
        xlab("") + ylab("") + lab.p #Labels
return(sp)
}

Tentang Data

Data kelompok kami merupakan data hasil web scraping dari laptopmedia.com dengan menggunakan extension web scraper dari chrome. Data ini memiliki 7 peubah yakni : Name (Nama laptop), Price (Harga), CPU, GPU, RAM, Display (layar), dan Storage.

Data tersebut perlu dibersihkan dan dimanage sehingga dapat di olah pada analisis selanjutnya.

Data input

install_load('readxl','dplyr','kableExtra')
data <- read_xlsx("data.xlsx", sheet="Laptop")
data <- data[,-c(1,2)]
cat("Jumlah Kolom:", ncol(data), "\n")
## Jumlah Kolom: 7
cat("Jumlah Baris:", nrow(data), "\n")
## Jumlah Baris: 10000
kable(head(data)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name Price CPU RAM GPU Display Storage
Lenovo ThinkPad T14 Gen 2 $146999 AMD Ryzen 7 5850U 20GB RAM AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD
HP 17 $111900 Intel Core i5-1335U 16GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD
Acer Predator Triton 300 $204900 Intel Core i7-11800H 64GB RAM NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD
ASUS Vivobook 17X $96999 AMD Ryzen 7 5800H 40GB RAM AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD
HP 17 $71299 Intel Core i5-1335U 12GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD
Dell Vostro 7620 $157900 Intel Core i7-12700H 24GB RAM NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD

Cek Missing Data

Penting untuk melihat ada tidaknya missing data.

# Mencari indeks baris dan kolom yang mengandung NA
na.idx <- which(is.na(data), arr.ind = TRUE)
cat("Banyaknya data NA : ", nrow(na.idx))
## Banyaknya data NA :  9
# Menampilkan data raw dengan baris dan kolom yang mengandung NA
install_load('kableExtra','dplyr','DT')

#Menampilkan tabel
kable(data[                        # Subsetting
                unique(na.idx[, 1]),   # Vektor indeks baris yang mengandung NA
                unique(na.idx[, 2])  ] # Vektor indeks kolom yang mengandung NA
      # Style Tabel
      ) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Display Storage
NA 256GB SSD
NA 256GB SSD
NA 512GB SSD
NA 1000GB HDD
NA 256GB SSD
NA 64GB SSD
13.3”, Full HD (1920 x 1080), IPS NA
14.0”, HD (1366 x 768), TN NA
11.6”, HD (1366 x 768), IPS NA

Hapus Data NA

Karena peubah diatas sulit untuk diduga maka kami putuskan untuk menghapus data NA tersebut.

data <- data[ -unique(na.idx[, 1]),  ]
cat("Jumlah Baris:", nrow(data), "\n")
## Jumlah Baris: 9991

1. Brand Classification

Klasifikasi brand ini diperlukan agar kita dapat melihat lebih jelas sebaran brand yang dijual pada e-commerce ini maupun untuk analisis selanjutnya.

# Install dan muat paket stringr jika belum diinstal
install_load('stringr')

# Daftar kata kunci merek
brands <- c(
    "HP", "Hewlett-Packard", "Acer", "Dell", "Lenovo", "ASUS",
    "MSI", "Alienware", "Apple", "LG", "Samsung", "Aorus", "Gigabyte",
    "Razer", "Microsoft", "Panasonic", "Chuwi", "Toshiba", "Fusion5")

# Fungsi untuk menetapkan merek berdasarkan kata kunci
assign_brand <- function(data) {
  for (brand_keywords in brands) {
    if (any(str_detect(tolower(data), tolower(brand_keywords)))) {
      return(brand_keywords[1])  # Ambil merek pertama yang cocok
    }
  }
  return("Tidak Diketahui")
}

# Menambahkan kolom brand berdasarkan fungsi
data$Brand <- sapply(data$Name, assign_brand)

# Tampilkan hasil
kable(head(data)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name Price CPU RAM GPU Display Storage Brand
Lenovo ThinkPad T14 Gen 2 $146999 AMD Ryzen 7 5850U 20GB RAM AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo
HP 17 $111900 Intel Core i5-1335U 16GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP
Acer Predator Triton 300 $204900 Intel Core i7-11800H 64GB RAM NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer
ASUS Vivobook 17X $96999 AMD Ryzen 7 5800H 40GB RAM AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS
HP 17 $71299 Intel Core i5-1335U 12GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP
Dell Vostro 7620 $157900 Intel Core i7-12700H 24GB RAM NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell

a. Sebaran Brand Laptop

install_load('hrbrthemes')
# Membuat bar chart persentase
ggplot(data = data %>% count(Brand) %>% # banyaknya laptop brand x
  mutate(perc = round(n / sum(n) * 100)), #buat persentase
       aes(x = reorder(Brand, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 8, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "\nBrand", y = "Persentase (%)", 
       title = "Sebaran Brand Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 10)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, face = "bold"),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

b. Brand to dummy variable

Singkat nya peubah Dummy memisahkan setiap kategori ke beberapa kolom. Dengan isi 1 atau TRUE yang kategori nya sesuai, dan 0 atau FALSE untuk kategori lainnya. Seperti contoh gambar di atas.

Namun cara diatas sangat memakan waktu dan memakan memori. Untung nya R dapat mengenali lebih advance yakni dengan tipe variabel factor. Karena factor memiliki level atau urutan nilai kategori yang bisa di ubah sesuka hati. Seperti ini factor(data$Brand, levels = c('HP','Acer',...)). Namun untuk default nya, R mengurutkan berdasarkan abjad.

Terdapat Fungsi relevel() yang digunakan dalam konteks peubah dummy untuk menentukan referensi atau kategori dasar. Namun ini hanya menggantikan posisi level 1, dengan ref yang diberikan. Sisanya mengurut sesuai abjad.

Ketika membuat peubah dummy untuk variabel kategorikal dengan lebih dari dua kategori, R secara otomatis memilih satu kategori sebagai referensi dan yang lainnya sebagai peubah dummy. Referensi yang diubah dapat mempengaruhi hasil analisis regresi karena perubahan dalam perbandingan dengan referensi. Jadi, pemilihan referensi ini perlu diperhatikan dalam konteks analisis statistik.

Berikut beberapa pertimbangan untuk memilih referensi yang baik:

  1. Interpretasi yang Jelas: Pilih kelompok referensi yang mudah diinterpretasikan. Ini akan membuat hasil analisis lebih mudah dipahami. Misalnya, jika Anda menganalisis jenis produk (A, B, C), mungkin produk yang paling umum atau biasa digunakan adalah pilihan yang baik untuk referensi.

  2. Pentingnya Variabel: Pilih kelompok yang memiliki relevansi atau signifikansi tertentu dalam konteks analisis Anda sebagai referensi. Ini dapat membantu Anda memahami efek perbedaan antara kelompok tersebut dengan kelompok lain.

  3. Eksplanasi Variabel Lain: Terkadang pemilihan referensi dapat memengaruhi hasil analisis. Misalnya, dalam analisis regresi logistik, referensi dapat mempengaruhi bagaimana koefisien variabel lain diinterpretasikan.

  4. Kemudahan Analisis: Pilih kelompok referensi yang memudahkan perbandingan dengan kelompok lainnya. Ini dapat membuat hasil analisis lebih intuitif dan bermakna.

  5. Konteks Bisnis atau Penelitian: Pertimbangkan konteks bisnis atau penelitian Anda. Misalnya, jika Anda sedang melakukan penelitian pasar, referensi yang cocok mungkin adalah produk atau merek yang paling dikenal atau paling banyak digunakan di pasar.

  6. Efeknya pada Regresi: Pahami bahwa pemilihan referensi dapat mempengaruhi koefisien dan interpretasi dalam analisis regresi. Koefisien peubah dummy akan mengukur perbedaan antara kelompok referensi dengan kelompok lainnya.

  7. Perbandingan yang Relevan: Pastikan perbandingan antara kelompok lain dengan kelompok referensi memiliki makna dalam konteks analisis Anda.

Untuk peubah brand, kami memilih Brand HP Sebagai referensi, karena merupakan kategori dengan jumlah terbanyak.

data <- data %>% 
  mutate(`Brand` = relevel(as.factor(data$Brand), ref = "HP"))
str(data$Brand)
##  Factor w/ 18 levels "HP","Acer","Alienware",..: 11 1 2 6 1 8 6 6 1 11 ...
##  - attr(*, "names")= chr [1:9991] "Lenovo ThinkPad T14 Gen 2" "HP 17" "Acer Predator Triton 300" "ASUS Vivobook 17X" ...
levels(data$Brand)
##  [1] "HP"        "Acer"      "Alienware" "Aorus"     "Apple"     "ASUS"     
##  [7] "Chuwi"     "Dell"      "Fusion5"   "Gigabyte"  "Lenovo"    "LG"       
## [13] "Microsoft" "MSI"       "Panasonic" "Razer"     "Samsung"   "Toshiba"

2. Price to Numeric

Price Memiliki karakter $ yang menandakan satuan USD. Agar dapat dianalisis lebih lanjut, kami menghapus $ lalu menjadikannya sebagai peubah numerik dan membaginya dengan \(100\), karena 2 digit dari belakang merupakan cent . Selain Price (USD) agar memudahkan dalam membaca nilai mata uang, kami juga membuat peubah tambahan yakni Price (IDR) dengan mengalikan setiap \(1\) USD dengan \(15,355.40\) (Nilai \(1\) USD ke IDR Sekarang).

data <- data %>%
  mutate(`Price (USD)` = as.numeric(gsub("\\$", "", Price)) / 100,
         `Price (IDR)` =  `Price (USD)` * 15355.40 ) %>%
  select(-Price)
kable(head(data)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU RAM GPU Display Storage Brand Price (USD) Price (IDR)
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U 20GB RAM AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284
HP 17 Intel Core i5-1335U 16GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693
Acer Predator Triton 300 Intel Core i7-11800H 64GB RAM NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215
ASUS Vivobook 17X AMD Ryzen 7 5800H 40GB RAM AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584
HP 17 Intel Core i5-1335U 12GB RAM Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247
Dell Vostro 7620 Intel Core i7-12700H 24GB RAM NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177

a. Sebaran Harga Laptop

install_load('ggridges','hrbrthemes','viridis')
ggplot(data, aes(x=`Price (USD)`, y=Brand, fill=Brand)) + geom_density_ridges() +
  #COLORING
  scale_fill_viridis(alpha = 0.75, #Opacity
                     begin = 0.1, #Color pallte scale begins
                     end = 0.9, #Color pallte scale ends
                     direction = -1, #Flip color scale
                     discrete = T, #Discrete Value
                     option = "D") + #Color Palette
  theme_modern_rc(axis_title_just = "center", base_size = 16, 
                  axis_title_size = 25, plot_title_size = 30) +
  theme(plot.title = element_text(hjust=0.5),legend.position = "none") +
  labs(x = "\nHarga (USD)",y = "Brand Laptop\n", 
       title = "Sebaran Harga Brand Laptop")

summary(data$`Price (USD)`)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     110     810    1236    1487    1799   11812
summary(data$`Price (IDR)`)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
##   1689094  12437720  18979121  22838230  27624365 181371689

Dari sebarannya, terlhiat bahwa mayoritas sebaran berdasarkan brand nya, menjulur ke kanan. Artinya lebih banyak harga laptop yang lebih murah daripada yang mahal. Sekitar \(75\%\) laptop harganya dibawah \(1,800\$\) (\(27.6\) jt IDR). Harga laptop paling murah yakni \(110\$\) atau sekitar \(1.7\) jt IDR. Dan Harga laptop paling mahal yakni \(11,812\$\) atau sekitar \(181\) jt IDR.

Contoh Model Linear dengan peubah dummy.

model <- lm(`Price (USD)` ~ `Brand`,data=data)
summary(model)
## 
## Call:
## lm(formula = `Price (USD)` ~ Brand, data = data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2707.1  -590.7  -194.7   327.5 10325.9 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     1273.32      17.15  74.246  < 2e-16 ***
## BrandAcer         79.01      33.73   2.343 0.019172 *  
## BrandAlienware  1107.63     113.54   9.756  < 2e-16 ***
## BrandAorus      2817.81      93.84  30.029  < 2e-16 ***
## BrandApple       842.14     156.58   5.378 7.69e-08 ***
## BrandASUS        212.38      28.87   7.355 2.05e-13 ***
## BrandChuwi      -914.32     972.13  -0.941 0.346965    
## BrandDell         75.68      36.66   2.064 0.039010 *  
## BrandFusion5   -1073.33     972.13  -1.104 0.269574    
## BrandGigabyte   1301.88     132.18   9.849  < 2e-16 ***
## BrandLenovo      -31.68      30.41  -1.042 0.297602    
## BrandLG          249.14      72.39   3.442 0.000581 ***
## BrandMicrosoft   303.93     175.41   1.733 0.083187 .  
## BrandMSI        1148.00      35.91  31.968  < 2e-16 ***
## BrandPanasonic  2512.93     486.29   5.168 2.42e-07 ***
## BrandRazer       895.57     270.12   3.315 0.000918 ***
## BrandSamsung    -288.01     158.60  -1.816 0.069416 .  
## BrandToshiba     715.68     687.50   1.041 0.297908    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 972 on 9973 degrees of freedom
## Multiple R-squared:  0.1777, Adjusted R-squared:  0.1763 
## F-statistic: 126.8 on 17 and 9973 DF,  p-value: < 2.2e-16

Terlihat bahwa tidak ada Brand HP , karena HP dijadikan sebagai referensi sebelumnya.

3. RAM to Numeric

Selanjutnya, kami menghapus “GB RAM” pada RAM dan mengubahnya menjadi numerik agar dapat dianalisis.

data <- data %>%
  mutate(`Ram (GB)` = as.numeric(gsub("GB RAM", "", RAM))) %>%
  select(-RAM)
kable(head(data)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB)
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284 20
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693 16
Acer Predator Triton 300 Intel Core i7-11800H NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215 64
ASUS Vivobook 17X AMD Ryzen 7 5800H AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584 40
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247 12
Dell Vostro 7620 Intel Core i7-12700H NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177 24

a. Sebaran RAM Laptop

# Membuat bar chart persentase
ggplot(data = data %>% count(`Ram (GB)`) %>% # banyaknya laptop brand x
                  mutate(perc = round(n / sum(n) * 100)), #buat persentase, 
       aes(x = reorder(`Ram (GB)`, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 8, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "\nRAM (GB)", y = "Persentase (%)", 
       title = "Sebaran RAM Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 1)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, vjust =0.5,
                                  face = "bold", margin = margin(b = 50)),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

Terlihat bahwa RAM laptop terbanyak memiliki kapasitas \(16\)GB, sedangkan yang terkecil adalah \(0\)GB.

Ini memang agak aneh, tapi setelah kami cek kembali, ternyata memang ada laptop dengan RAM \(0\)GB.

4. Storage to Numeric

Setelah itu kami akan mengubah Storage Menjadi numerik dengan cara memisahkan “SSD” & “HDD” ke kolom Storage Type.

storage <- data %>%
mutate(`Storage (GB)` = as.numeric(str_extract(Storage, "\\d+")),
         `Storage Type` = str_extract(Storage, "(SSD|HDD)")) %>% 
  select(`Storage (GB)`,`Storage Type`)
kable(head(storage)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Storage (GB) Storage Type
2000 SSD
1000 HDD
4000 SSD
2000 SSD
1000 SSD
512 SSD

a. Sebaran Storage Laptop

Pie Chart SSD & HDD

plot.p(dt = storage$`Storage Type`, title = "Porporsi SSD dan HDD")

Terlihat bahwa \(94.1\%\) laptop memiliki tipe peyimpanan SSD. Sunggu perbedaan yang sangat jauh.

Sebaran SSD

# Membuat bar chart persentase
ggplot(data = storage %>%
        filter(grepl("SSD", `Storage Type`, ignore.case = TRUE))
        %>% count(`Storage (GB)`) %>% # banyaknya laptop brand x
                  mutate(perc = round(n / sum(n) * 100)), #buat persentase, 
       aes(x = reorder(`Storage (GB)`, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 8, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "\nSSD (GB)", y = "Persentase (%)", 
       title = "Sebaran SSD Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 1)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, vjust =0.5,
                                  face = "bold", margin = margin(b = 50)),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

Laptop dengan total penyimpanan \(1000\) GigaByte ( \(1\) TerraByte) SSD merupakan total penyimpanan yang paling banyak dimiliki oleh laptop.

kable(data[data$`Storage` == "16GB SSD", ]) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB)
HP Chromebook 11 G5 EE Intel Celeron N3060 Intel HD Graphics 400 (Braswell) 11.6”, HD (1280 x 800), TN 16GB SSD HP 195.00 2994303 2
Acer Chromebook 11 (CB3-131) Intel Celeron N2840 Intel HD Graphics (Bay Trail) 11.6”, HD (1366 x 768), IPS 16GB SSD Acer 499.99 7677546 4
Dell Chromebook 11 3181 Intel Celeron N3060 Intel HD Graphics 400 (Braswell) 11.6”, HD (1366 x 768), TN 16GB SSD Dell 287.88 4420513 4
Samsung Chromebook 4 Intel Celeron N4020 Intel UHD Graphics 600 11.6”, HD (1366 x 768), TN 16GB SSD Samsung 164.97 2533180 4
Acer Chromebook 14 (CB3-431) Intel Celeron N3060 Intel HD Graphics 405 (Braswell) 14.0”, HD (1366 x 768), IPS 16GB SSD Acer 199.00 3055725 4
HP Chromebook 11 G6 EE Intel Celeron N3350 Intel HD Graphics 500 (Apollo Lake) 11.6”, HD (1366 x 768), TN 16GB SSD HP 294.02 4514795 4
HP Chromebook 11 G5 Intel Celeron N3050 Intel HD Graphics 400 (Braswell) 11.6”, HD (1366 x 768), IPS 16GB SSD HP 161.00 2472219 2
HP Chromebook 11 (11-v000nr) Intel Celeron N3060 Intel HD Graphics 400 (Braswell) 11.6”, HD (1366 x 768), TN 16GB SSD HP 147.50 2264922 2
ASUS TUF Gaming A17 AMD Ryzen 9 7940HS NVIDIA GeForce RTX 4060 (Laptop, 140W) 17.3”, Full HD (1920 x 1080), 144 Hz, IPS 16GB SSD ASUS 4389.00 67394851 64

Memang agak mengejutkan, bahwa ternyata ada laptop yang hanya memiliki penyimpanan \(16\) GB SSD saja. Tidak ada keterangan Bahwa laptop tersebut memiliki penyimpanan Hybrid dengan tambahan HDD. Namun kami yakin laptop tersebut pasti memiliki penyimpanan HDD tambahan. Karena terlihat bahwa ada laptop yang memiliki Spesifikasi gahar dengan harga yang mahal pula, namun Storage hanya \(16\) GB SSD saja. Laptop tersebut adalah ASUS TUF Gaming A17 dengan harga \(67.4\) jt IDR.

Tapi karena keterbatasan informasi dari data hasil scraping. Kami akan melanjutkan dengan data ini dahulu saja. Jika memungkinkan untuk scraping ulang, maka akan kami scraping ulang.

Sebaran HDD

# Membuat bar chart persentase
ggplot(data = storage %>%
        filter(grepl("HDD", `Storage Type`, ignore.case = TRUE))
        %>% count(`Storage (GB)`) %>% # banyaknya laptop brand x
                  mutate(perc = round(n / sum(n) * 100)), #buat persentase, 
       aes(x = reorder(`Storage (GB)`, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 10, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "\nHDD (GB)", y = "Persentase (%)", 
       title = "Sebaran HDD Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 1)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, vjust =0.5,
                                  face = "bold", margin = margin(b = 50)),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

Kebanyakan laptop dengan tipe penyimpanan HDD memiliki total penyimpanan \(1\) TerraByte.

b. Scoring Storage

Scoring merupakan salah satu metode untuk mengurangi adanya autokorelasi pada analsis regresi. Untuk mengurangi adanya autokorelasi pada 2 peubah diatas yakni Storage (GB) dengan Storage Type, Maka kami melakukan scoring dengan mempertimbangkan hal berikut:

  • Dalam hal kinerja, SSD dapat diperkirakan sekitar \(5\) hingga \(10\) kali lebih cepat daripada HDD dalam hal kecepatan baca/tulis data.

  • Dalam hal harga, SSD dapat diperkirakan sekitar \(2\) hingga \(5\) kali lebih mahal per gigabyte dibandingkan HDD.

  • Dalam hal kapasitas, HDD dapat memiliki kapasitas yang lebih besar hingga \(2\) hingga \(4\) kali lipat dari SSD dalam harga yang sama.

Pemberian bobot yang lebih merata dengan menggunakan nilai tengah seperti \(\frac{7.5}{3.5}\) untuk SSD dan \(\frac{3.5}{7.5}\) untuk HDD adalah pendekatan yang lebih seimbang dan simetris. Ini memberikan penekanan yang relatif setara pada kedua faktor, baik kinerja (SSD) maupun kapasitas (HDD).

Pendekatan ini menghindari pemberian bobot yang sangat ekstrem dan cenderung memberikan penilaian yang lebih adil terhadap kedua faktor tersebut.

storage <- storage %>%
  mutate(
    `Storage Score` = ifelse(`Storage Type` == "SSD", `Storage (GB)` * (7.5/3.5), 
                           `Storage (GB)` * (3.5/7.5))
  )
kable(head(storage)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Storage (GB) Storage Type Storage Score
2000 SSD 4285.7143
1000 HDD 466.6667
4000 SSD 8571.4286
2000 SSD 4285.7143
1000 SSD 2142.8571
512 SSD 1097.1429

c. Merge Data

data <- data %>%
  mutate(`Storage Score` = storage$`Storage Score`)
kable(head(data)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB) Storage Score
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284 20 4285.7143
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693 16 466.6667
Acer Predator Triton 300 Intel Core i7-11800H NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215 64 8571.4286
ASUS Vivobook 17X AMD Ryzen 7 5800H AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584 40 4285.7143
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247 12 2142.8571
Dell Vostro 7620 Intel Core i7-12700H NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177 24 1097.1429

5. Display Classification & Scoring

Setelah Storage, kita lanjut ke peubah selanjutnya yakni Display. Ada beberapa komponen dalam display, terutama pada data yang kami miliki ada 4 komponen, Yakni Screen Size, Resolution, Refresh Rate, dan Screen Type. Kami melakukan pemisahan keempat komponen tersebut menjadi 4 kolom yang berbeda.

a. Refresh Rate

Ada baiknya kita mengetahui bahwa:

  • Refresh rate mengukur berapa kali layar dapat menggambar atau memperbarui gambar per detik, diukur dalam Hertz (Hz).

  • Refresh rate yang lebih tinggi dapat menghasilkan tampilan yang lebih halus, yang bermanfaat dalam gaming dan aplikasi bergerak cepat.

  • Sebagian besar laptop memiliki refresh rate 60Hz, tetapi beberapa laptop gaming mungkin memiliki refresh rate 120Hz atau bahkan lebih tinggi.

Karena kami melihat banyak sekali laptop tanpa refresh rate. Maka kami memutuskan untuk menambahkannya dengan refresh rate minimal pada laptop.

Mengutip dari chat gpt bahwa nilai minimal refresh rate (Hz) pada layar laptop umumnya adalah 60Hz. Layar dengan refresh rate 60Hz sudah cukup umum digunakan dan memberikan tampilan yang lancar untuk sebagian besar tugas komputasi sehari-hari. Beberapa laptop gaming dan monitor mungkin memiliki refresh rate yang lebih tinggi, seperti 120Hz, 144Hz, atau bahkan lebih tinggi, yang dirancang untuk memberikan pengalaman gaming yang lebih halus.

Refresh rate 30Hz mungkin terlalu rendah dan dapat menyebabkan tampilan layar terlihat kurang responsif dan cenderung “berkedip” dalam beberapa kasus. Oleh karena itu, kami memutuskan untuk memberikan nilai 60Hz kepada laptop yang tidak memiliki keterangan refresh rate.

display <- data %>%
  separate(Display, into = c("Screen Size (Inch)", "Resolution", 
                             "Screen Type","Refresh Rate (Hz)" ), 
           sep = ", ", remove = FALSE) %>%
  mutate(
    # Menghapus karakter " dan mengubah menjadi numerik
    `Screen Size (Inch)` = as.numeric(gsub("[^0-9.]", "", `Screen Size (Inch)`)), 
    #Tukar Kolom jika ada hz
    temp = `Refresh Rate (Hz)`,
    #Ubah hz jadi numerik
    `Refresh Rate (Hz)` = ifelse(grepl("Hz", `Screen Type`), 
                                 as.numeric(gsub("[^0-9.]", "", `Screen Type`)), 
                      #Jika tidak ada, beri nilai minimal hz laptop yakni 60 hz
                                 60), 
    `Screen Type` = ifelse(grepl("Hz", `Screen Type`), temp, `Screen Type`)
  ) %>%
  select(`Screen Size (Inch)`, Resolution, `Screen Type`, `Refresh Rate (Hz)`)
kable(head(display)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Screen Size (Inch) Resolution Screen Type Refresh Rate (Hz)
14.0 Full HD (1920 x 1080) IPS 60
17.3 Full HD (1920 x 1080) IPS 60
15.6 Full HD (1920 x 1080) IPS 144
17.3 Full HD (1920 x 1080) IPS 60
17.3 Full HD (1920 x 1080) IPS 60
16.0 WUXGA (1920 x 1200) IPS 60

- Cek NA

cat(" Jumlah Screen Size NA  :", sum(is.na(display$`Screen Size (Inch)`)), "\n",
     "Jumlah Resolution NA   :", sum(is.na(display$Resolution)), "\n",
     "Jumlah Screen Type NA  :", sum(is.na(display$`Screen Type`)), "\n",
     "Jumlah Refresh Rate NA :", sum(is.na(display$`Refresh Rate (Hz)`)), "\n"
    )
##  Jumlah Screen Size NA  : 0 
##  Jumlah Resolution NA   : 0 
##  Jumlah Screen Type NA  : 27 
##  Jumlah Refresh Rate NA : 0
na.idx <- which(is.na(display[,3]), arr.ind = TRUE)
kable(data[ unique(na.idx[, 1]), unique(na.idx[, 2]) +3 ]) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Display
14.2”, Liquid Retina (3024 x 1964), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz
13.5”, PixelSense (2256 x 1504)
16.2”, Liquid Retina (3456 x 2234), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz
14.2”, Liquid Retina (3024 x 1964), 120 Hz
15.6”, Full HD (1920 x 1080)
14.2”, Liquid Retina (3024 x 1964), 120 Hz
14.2”, Liquid Retina (3024 x 1964), 120 Hz
14.2”, Liquid Retina (3024 x 1964), 120 Hz
13.5”, PixelSense (2256 x 1504)
13.5”, PixelSense (2256 x 1504)
14.2”, Liquid Retina (3024 x 1964), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz
13.5”, PixelSense (2256 x 1504)
13.5”, PixelSense (2256 x 1504)
15.6”, Full HD (1920 x 1080)
14.2”, Liquid Retina (3024 x 1964), 120 Hz
13.5”, PixelSense (2256 x 1504)
13.5”, PixelSense (2256 x 1504)
16.2”, Liquid Retina (3456 x 2234), 120 Hz
15.6”, Full HD (1920 x 1080)
14.2”, Liquid Retina (3024 x 1964), 120 Hz
14.2”, Liquid Retina (3024 x 1964), 120 Hz
16.2”, Liquid Retina (3456 x 2234), 120 Hz

b.1 Tipe Layar

Penting untuk mengetahui bahwa:

  • Tipe layar mengacu pada teknologi yang digunakan dalam pembuatan layar.

  • Beberapa tipe layar umum meliputi:

    • IPS (In-Plane Switching): Layar jenis ini dikenal dengan sudut pandang yang luas dan reproduksi warna yang baik.

    • OLED (Organic Light-Emitting Diode): OLED menghasilkan warna yang kaya dan kontras tinggi.

    • LCD (Liquid Crystal Display): Layar LCD adalah jenis yang umum dan cenderung lebih terjangkau.

    • TN (Twisted Nematic): Biasanya digunakan dalam layar murah dan memiliki sudut pandang yang lebih terbatas.

  • Tipe layar dapat mempengaruhi kualitas tampilan, reproduksi warna, dan sudut pandang.

Seperti yang kita lihat pada ###Cek NA, Yang NA Hanya tersisa pada Screen Type saja. Karena setiap layar pasti memiliki tipe nya oleh karena itu kami menanyakan kepada chat gpt “Apa tipe layar minimal pada laptop?” Berikut ulasannnya :
Tipe layar minimal laptop adalah layar LCD (Liquid Crystal Display). Layar LCD adalah teknologi layar yang paling umum digunakan dalam laptop dan perangkat komputer lainnya. LCD menggunakan kristal cair yang berada di antara dua lapisan kaca yang kemudian dikendalikan untuk mengatur cahaya dan menghasilkan gambar.

Dengan demikian kami memutuskan untuk menambahkan Tipe LCD ke kolom Screen Type yang NA

display <- display %>% 
  mutate(`Screen Type` = ifelse(is.na(`Screen Type`), "LCD", `Screen Type`))
kable(
  display %>%
  group_by(`Screen Type`) %>%
  summarise(Total = n())
) %>%  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Screen Type Total
IPS 7944
LCD 27
OLED 338
TN 1682

b.2 Screen Type Value Number

Setelah melihat semua tipe layar yang ada, kami ingin mengubah tipe layar tersebut menjadi numerik berdasarkan kualitas nilai mereka. Kami meminta bantuan chat gpt untuk memberikan nilai tersebut. Sebelum itu penting untuk mengetahui kualitas tipe layar yang ada, sebagai berikut:

  1. OLED (Organic Light-Emitting Diode):

    • OLED memiliki kualitas gambar yang luar biasa dengan kontras yang sangat tinggi, warna yang tajam, dan sudut pandang yang luas.

    • Reproduksi warna pada layar OLED sangat akurat dan hidup.

    • Tidak ada pencahayaan latar belakang, sehingga hitam murni dan kecerahan yang luar biasa.

    • Biasanya digunakan dalam TV premium dan beberapa monitor kelas atas.

  2. IPS (In-Plane Switching):

    • IPS menawarkan reproduksi warna yang sangat baik dan sudut pandang yang luas.

    • Kontras yang baik dan gambar yang tajam, meskipun tidak sebaik OLED.

    • Digunakan dalam monitor profesional, laptop, dan beberapa TV.

  3. LCD (Liquid Crystal Display):

    • LCD dengan panel IPS atau VA dapat memberikan kualitas gambar yang baik dengan harga yang lebih terjangkau.

    • Kualitas gambar bisa bervariasi tergantung pada jenis panel LCD.

    • Digunakan dalam berbagai perangkat, termasuk monitor, laptop, dan TV.

  4. TN (Twisted Nematic):

    • TN memiliki waktu respon yang sangat cepat, cocok untuk permainan.

    • Namun, sudut pandang yang terbatas dan reproduksi warna yang kurang akurat.

    • Digunakan dalam monitor gaming yang terjangkau.

Sehingga jika diberi nilai akan menjadi:

  1. OLED (Organic Light-Emitting Diode): 9

    • OLED memiliki kualitas gambar terbaik dengan kontras tinggi, warna hidup, dan sudut pandang yang luas. Oleh karena itu, kita memberikan nilai tertinggi.
  2. IPS (In-Plane Switching): 7

    • IPS menawarkan kualitas gambar yang sangat baik dan sudut pandang yang luas, meskipun tidak sebaik OLED. Tetapi nilai ini tetap tinggi karena IPS masih merupakan pilihan yang sangat baik.
  3. LCD (Liquid Crystal Display): 5

    • LCD dengan panel IPS atau VA dapat memberikan kualitas gambar yang baik dengan harga yang lebih terjangkau. Nilai ini mencerminkan kualitas yang baik tetapi tidak sebaik OLED atau IPS.
  4. TN (Twisted Nematic): 3

    • TN memiliki waktu respon yang cepat, tetapi sudut pandang yang terbatas dan reproduksi warna yang kurang akurat. Oleh karena itu, nilai ini lebih rendah.
display <- display %>%
  mutate(
    `Screen Type` = case_when(
      `Screen Type` == "OLED" ~ "9",  `Screen Type` == "IPS" ~ "7",   
      `Screen Type` == "LCD" ~ "5",   `Screen Type` == "TN" ~ "3",    
      TRUE ~ `Screen Type`
    ), `Screen Type` = as.numeric(`Screen Type`)
  )
kable(head(display)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Screen Size (Inch) Resolution Screen Type Refresh Rate (Hz)
14.0 Full HD (1920 x 1080) 7 60
17.3 Full HD (1920 x 1080) 7 60
15.6 Full HD (1920 x 1080) 7 144
17.3 Full HD (1920 x 1080) 7 60
17.3 Full HD (1920 x 1080) 7 60
16.0 WUXGA (1920 x 1200) 7 60

c.1 Resolusi layar

Penting untuk mengetahui apa itu resolusi layar.

  • Resolusi adalah jumlah piksel yang dapat ditampilkan pada layar.

  • Resolusi umumnya diukur dalam format “lebar x tinggi” (misalnya, 1920 x 1080), yang menunjukkan jumlah piksel horizontal dan vertikal yang terdapat pada layar.

  • Semakin tinggi resolusi, semakin tajam dan detail tampilan gambar dan teksnya.

Karena kami lihat banyak sekali jenis resolusi layar yang punya nama, jadi kami memutuskan untuk melihat semua jenis nya.

kable(
  display %>%
  group_by(`Resolution`) %>%
  summarise(Total = n())
) %>%  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Resolution Total
QHD (2560 x 1440) 63
(2496 x 1664) 3
(2560 x 1664) 5
2.2K (2240 x 1400) 25
2.5K (2560 x 1440) 1
2.8K (2880 x 1620) 7
2.8K (2880 x 1800) 85
2K (2256 x 1504) 8
3.2K (3200 x 2000) 12
3.5K (3456 x 2160) 8
3K (2880 x 1800) 5
3K (3000 x 2000) 7
3K (3072 x 1920) 48
3K (3240 x 2160) 3
3K2K (3000 x 2000) 1
3К (2736 x 1824) 4
4K UHD (3840 x 2160) 110
4K UHD (3840 x 2400) 4
4K UHD+ (3840 x 2400) 4
FHD (1920 x 1080) 131
FHD (1920 x 1200) 5
FHD (1920x1080) 2
FHD+ (1920 x 1200) 158
FHD+ (1920 x 1280) 4
FHD+ (2160 x 1440) 2
Full HD (1920 x 1080) 5926
HD (1280 x 800) 1
HD (1366 x 768) 1027
HD+ (1366 x 912) 2
HD+ (1600 x 900) 349
Liquid Retina (2880 x 1864) 7
Liquid Retina (3024 x 1964) 9
Liquid Retina (3456 x 2234) 8
PixelSense (1536 x 1024) 3
PixelSense (2256 x 1504) 7
PixelSense (2880 x 1920) 2
PixelSense Flow (2400 x 1600) 1
QHD (2560 x 1440) 259
QHD (2560 x 1600) 94
QHD+ (2560 x 1600) 119
QHD+ (3000 x 2000) 2
QHD+ (3200 x 1800) 2
UHD+ (3840 x 2400) 30
WQHD (2160 x 1350) 3
WQHD (2560 x 1440) 139
WQHD+ (2880 x 1800) 1
WQUXGA (3840 x 2400) 75
WQUXGA (3840 x 2400) 36
WQXGA (2560 x 1600) 593
WQXGA (2560 x 1600) 8
WUXGA (1920 x 1200) 570
WUXGA (1920 x 1280) 2
WUXGA+ (1920 x 1280) 11

Terlihat bahwa semua namanya adalah seberapa besar kualitas resolusinya, Kecuali PixelSense.

PixelSense adalah tipe layar yang digunakan pada perangkat Microsoft Surface. Ini adalah layar sentuh yang sangat responsif dan mendukung penggunaan pena digital. Layar ini dirancang untuk produktivitas dan kreativitas.

Karena perbedaan inilah, kami memutuskan untuk memberikan bobot pada tipe layar PixelSense, dengan PixelSense \((1.125)\) dan PixelSense Flow \((1.25)\).

“PixelSense” dan “PixelSense Flow” memiliki karakteristik yang berbeda dalam hal kualitas gambar atau kemampuan layarnya. Sehingga memberikan bobot yang sedikit lebih tinggi kepada “PixelSense Flow” \((1.25)\) cukup mencerminkan perbedaan ini.

c.2 Multiply Resolution

Setelah eksplorasi tentang macam-macam tipe layar dan memberi bobot pada mereka, kami akan mengalikan resolusi tersebut. Sehingga resmi menjadi peubah numerik.

display <- display %>% 
  mutate( # Mencari semua kemungkinan pasangan angka dalam kolom "Resolution"
    Resolution_Num = str_extract_all(Resolution, "\\d{2,}"),
    # Mengambil pasangan angka yang memiliki dua angka di dalamnya
    Resolution_Num = sapply(Resolution_Num, 
                            function(x) if (length(x) == 2) paste(x, collapse = "x") else NA)
  ) %>% # Pisahkan "Width" dan "Height" dari "Resolution_Num"
  separate(Resolution_Num, into = c("Width", "Height"), sep = "x", 
           convert = TRUE, remove = FALSE) %>% 
# Berikan bobot jika ada kata PixelSense dalam kolom resolusi
  mutate(
    Resolution = ifelse(grepl("PixelSense", Resolution), 
                              Width * Height * 1.125, 
                              Width * Height)
  ) %>% select(-Resolution_Num, -Width, -Height) 
kable(head(display)) %>%  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Screen Size (Inch) Resolution Screen Type Refresh Rate (Hz)
14.0 2073600 7 60
17.3 2073600 7 60
15.6 2073600 7 144
17.3 2073600 7 60
17.3 2073600 7 60
16.0 2304000 7 60

d. Display Score

Akhirnya setelah mengubah keempat peubah display diatas menjadi numerik, kami akan menghitung total score yang dimiliki. Scoring merupakan salah satu metode untuk mengurangi adanya autokorelasi pada analsis regresi. Adapun formula untuk display score:

\[ \frac{\mathbf{Resolution\times Screen.Type}} {\mathbf{Screen.Size}} + \mathbf{Refresh.Rate} \]

Resolution dan Screen Type merupakan hal yang berfokus pada kualitas visual dan bisa dipadukan satu sama lain. Akan tetapi hal itu akan sia-sia jika Screen Size nya kecil. Bayangkan anda memiliki resolusi dan tipe layar yang tinggi, namun ukuran layar anda kecil. Apa yang ingin anda liat? Apakah anda menatap layar sangat dengat dengan mata anda? Tentu saja tidak!

Berbeda dengan Refresh Rate yang berfokus pada kecepatan layar. Baik kualitas visual maupun ukuran tidak terlalu mempengaruhi nilai nya. Sehingga kaidah score nya dibuat terpisah dengan penjumlahan.

display <- display %>% 
  mutate_all(rescale, to = c(10, 100)) %>% 
  mutate(`Display Score` = ((Resolution * `Screen Type`) / 
                             `Screen Size (Inch)`) + `Refresh Rate (Hz)`)
kable(head(display)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Screen Size (Inch) Resolution Screen Type Refresh Rate (Hz) Display Score
67.27273 21.53125 70 10 32.40414
94.27273 21.53125 70 10 25.98752
80.36364 21.53125 70 28 46.75460
94.27273 21.53125 70 10 25.98752
94.27273 21.53125 70 10 25.98752
83.63636 24.06250 70 10 30.13927

e. Merge Data

data <- data %>% bind_cols(`Display Score` = display$`Display Score`)
kable(head(data)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB) Storage Score Display Score
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284 20 4285.7143 32.40414
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693 16 466.6667 25.98752
Acer Predator Triton 300 Intel Core i7-11800H NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215 64 8571.4286 46.75460
ASUS Vivobook 17X AMD Ryzen 7 5800H AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584 40 4285.7143 25.98752
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247 12 2142.8571 25.98752
Dell Vostro 7620 Intel Core i7-12700H NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177 24 1097.1429 30.13927

6. Scoring CPU

Untuk mengukur score dari CPU ada yang namanya Benchmark. Benchmark CPU adalah proses pengukuran dan perbandingan kinerja unit pemrosesan pusat (CPU) pada komputer atau perangkat keras serupa. Tujuannya adalah untuk mengukur sejauh mana CPU dapat menjalankan berbagai tugas pemrosesan data dan instruksi perangkat lunak dalam berbagai skenario. Benchmark CPU membantu pengguna, peneliti, dan produsen perangkat keras dalam memahami kinerja CPU, membandingkannya dengan CPU lain, dan menilai bagaimana CPU tersebut berkinerja dalam berbagai aplikasi.

Biasanya pada data benchmark terdapat \(n\) , contohnya : \(12017.5^{n4}\) . \(n\) disini menyatakan banyaknya sampel atau ulangan yang dilakukan dalam test benchmark.

Ada 2 contoh untuk benchmark CPU yang populer yakni Cinebench dan Geekbench.

Cinebench:

  • Deskripsi: Cinebench adalah benchmark CPU yang dikembangkan oleh Maxon. Ini dirancang khusus untuk mengukur kinerja CPU dalam aplikasi grafis dan rendering 3D. Cinebench menggunakan perangkat lunak Cinema 4D untuk melakukan tes rendering dalam berbagai skenario, termasuk rendering tunggal dan multi-threaded.

  • Cara Kerja: Cinebench menghitung berapa lama CPU memerlukan waktu untuk menyelesaikan tugas rendering yang diberikan dalam skenario yang berbeda. Hasilnya adalah skor yang mencerminkan kemampuan CPU dalam tugas rendering grafis. Semakin tinggi skornya, semakin baik kinerja CPU dalam aplikasi seperti grafis dan rendering 3D.

  • Penggunaan: Cinebench sering digunakan oleh para profesional grafis, pengembang perangkat lunak, dan pengguna yang memiliki kebutuhan khusus dalam tugas rendering.

Geekbench:

  • Deskripsi: Geekbench adalah benchmark CPU yang dirancang oleh Primate Labs. Ini adalah benchmark sintetis yang mengukur kinerja CPU dalam berbagai tugas pemrosesan umum, termasuk perhitungan matematika, komunikasi memori, dan pengolahan data. Geekbench tersedia untuk berbagai platform, termasuk Windows, macOS, iOS, dan Android.

  • Cara Kerja: Geekbench menjalankan sejumlah tes sintetis yang mencakup berbagai jenis operasi CPU, seperti operasi integer dan floating-point. Kemudian, hasilnya diMergekan untuk menghasilkan skor single-core dan multi-core yang mencerminkan kinerja CPU dalam aplikasi umum.

  • Penggunaan: Geekbench adalah alat yang sering digunakan untuk membandingkan kinerja CPU dari berbagai merek dan model. Hasil Geekbench dapat memberikan gambaran umum tentang seberapa baik CPU dapat menangani berbagai tugas pemrosesan.

Kami membuat Score untuk CPU dengan data benchmark dari website notebookcheck.net dengan setting :

Setting ini agar mendapatkan seluruh data yang kami perlukan. Pastikan Checklist semuayang ada kecuali Show single scores on hover , Show only itmes with known benchmark results , Show Percent dan Still available (not archived).

Agar perhitungannya maksimal dan presisi, kami menggunakan seluruh benchmark yang ada, yakni sebanyak \(40\) data benchmark.

Berikut Metode kami :

  1. Scaling data benchmark
    Agar nilai setiap benchmark berada dalam skala yang sama (10 sampai 100)

  2. Mengubah data NA menjadi \(0\)
    Not Available atau Data yang tidak ada harus diubah menjadi \(0\) Agar dapat dijumlahkan.

  3. Memberi Bobot pada setiap Benchmark
    Chat GPT memberi saran untuk nilai bobot masing-masing :

    Dengan cara perkalian matriks antara data benchmark \((\mathbf{B})\) dengan matriks diagonal bobot \((\mathbf{D})\):

    \[ \mathbf{B}_{n\times40} \boldsymbol{\cdot} \mathbf{D}_{40\times40} \]
    dimana \(n=\) Banyaknya baris data

    \[ \begin{pmatrix} b_{1.1} & b_{1.2} & \cdots & b_{1.11}\\ \vdots & \vdots & \vdots & \vdots \\ b_{n.1} & b_{n.2} & \cdots & b_{n.11}\\ \end{pmatrix} \boldsymbol{\cdot} \begin{pmatrix} 5 & 0 & 0 & \cdots & 0 \\ 0 & 4 & 0 & \cdots & 0 \\ 0 & 0 & 4 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 7 \end{pmatrix} \]

  4. Menjumlahkan Total Score dari masing-masing Benchmark
    Menggunakan rowSums()

  5. Membagi nya dengan banyaknya Benchmark yang bukan \(0\) atau NA
    Agar adil
    harus dibagi. Jadi mirip seperti rata-rata. Namun bedanya jika kolom Bechmark A = \(0\). Maka tidak akan dibagi. Misalnya :
    Benchmark A : NA
    Benchmark B : NA
    Benchmark C : \(1405\)
    Benchmark D : \(3329\)

    Score : \(\frac{A + B + C + D}{not.NA.nor.0}\) Score : \(\frac{0 + 0 + 1405 + 3329}{0+0+1+1}\)
    Score : \(2367\)
    Sehingga akan diperoleh hasil yang ADIL

  6. Mengubah NaN menjadi \(0\)
    Tak lupa untuk mengubah Not a Number menjadi \(0\). Ini dihasilkan ketika satu baris \(0\) semua

Kenapa perlu scaling?. Mudahnya gini. Misalnya kita punya data dengan 2 Score. Score 1 memiliki rentang nliai dari \(10\ldots300\) sedangkan Score 2 dengan rendant \(1 \ldots 10\) . Untuk menghitung total score nya, tidak lah valid untuk langsung menjumlahkan nya.

Maka dari itu perlu scaling. Antara mengubah ke rentang skala Score 1 atau mengubah ke Score 2. Seperti ini:

rescale(c(10, 200, 230, 300), to = c(1, 10))
## [1]  1.000000  6.896552  7.827586 10.000000

Pada kasus Score CPU , Score ini tidak memiliki rentang nilai yang pasti (\(0 \ldots \infty\)). Sehingga cukup rescale(data, to = c(10, 100)) saja. Kami mengambil nilai terkecil yakni \(10\) dan nilai terbesar yakni \(100\) Sedangkan \(0\) untuk yang NA.

a. Seleksi Data

#Data Benchmark CPU
cpu <- read_xlsx("data_new.xlsx", sheet="CPU") %>%
       select(1, 15:ncol(.)) %>% #Ambil data benchmark nya saja 
  #Hapus selain numerik dan setelahnya, lalu Ubah jadi numerik
  mutate_at(vars(-1), ~as.numeric(gsub("[^0-9.].*$", "", .))) 
cat("Jumlah Baris:", nrow(cpu), "\n")
## Jumlah Baris: 1891
kable(head(cpu)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Model 3DMark06 CPU Cinebench R10 32Bit Single Cinebench R10 32Bit Multi Cinebench R11.5 CPU Single 64Bit Cinebench R11.5 64Bit Cinebench R15 CPU Single 64Bit Cinebench R15 CPU Multi 64Bit Cinebench R20 Single Cinebench R20 Cinebench R23 Single Core Cinebench R23 Multi Core SuperPI 1M* SuperPI 32M* wPrime 32 wPrime 1024 WinRAR 4.0 x264 Pass 1 x264 Pass 2 x265 TrueCrypt AES TrueCrypt Twofish TrueCrypt Serpent Blender(-) 7-Zip Single 7-Zip Geekbench 2 Geekbench 3 32 Bit Single-Core Score Geekbench 3 32 Bit Multi-Core Score Geekbench 4.1 - 4.4 64 Bit Single-Core Score Geekbench 4.1 - 4.4 64 Bit Multi-Core Score Geekbench 5.0 5.0 Single-Core Geekbench 5.0 5.0 Multi-Core Geekbench 5.4 Single-Core Geekbench 5.4 Multi-Core PassMark PerformanceTest Mobile V1 CPU Tests Sunspider 1.0 Total Score(-) Octane V2 Total Score Jetstream 2 Speedometer WebXPRT 3
AMD Ryzen Threadripper PRO 3995WX 16656.0 5596.0 52743.0 2.12 54.30 195 9706.0 488.0 23571.0 1249.0 61102.0 9.81 730.00 6.11 25.41 6689 264.00 192.50 46.60 26.0 4.8 2.9 47.8 5021 140172 NA NA NA 5567 80545 1266 31711 1720.0 14881.0 NA NA NA NA NA 229
AMD Ryzen 9 7950X 21108.5 8508.0 72480.0 3.70 68.61 316 6095.0 778.0 14538.0 2001.0 37353.0 6.35 312.55 1.67 30.81 15779 383.00 274.00 43.80 32.5 4.5 2.8 85.0 8211 158445 NA NA NA 9023 86708 2143 23931 2245.5 24403.0 NA NA NA NA NA 377
Intel Core i9-13900K 20191.5 12017.5 87738.0 3.87 67.50 324 5959.0 849.5 14620.5 2238.5 38271.5 5.70 293.25 2.05 84.20 14271 419.25 264.75 40.70 22.9 5.4 2.9 84.0 7272 146984 NA NA NA 9598 85336 2197 23664 2286.0 24033.0 NA NA NA NA NA 368
AMD Ryzen 9 7950X3D 20279.0 16551.0 138015.0 3.86 64.59 326 5974.0 795.0 14188.0 2053.0 36291.0 6.11 305.11 2.01 33.88 15779 392.50 265.50 42.40 26.9 4.2 2.8 86.0 8321 159341 NA NA NA 9240 87922 2183 23720 2311.0 24343.0 NA NA NA NA NA 383
AMD Ryzen 9 7900X 21284.0 8623.0 68579.5 3.83 54.66 323 4820.5 782.5 11471.5 2016.5 29300.0 6.14 313.44 1.80 40.31 17225 376.00 241.00 36.85 14.8 2.8 1.5 106.0 8269 127195 NA NA NA 9275 77033 2196 20658 2294.0 20667.5 NA NA NA NA NA 383
Intel Core i7-13700K 18153.0 11278.0 85748.0 3.66 52.98 303 4577.0 815.0 11742.0 2114.0 30753.0 6.19 317.81 2.31 170.22 12835 406.00 232.00 34.00 15.8 4.0 2.2 106.0 7062 112359 NA NA NA 8955 69210 2064 19217 2081.0 19719.0 NA NA NA NA NA 348

b. Scoring

install_load('scales')
cpu.score <- cpu %>%
  mutate_at(vars(2:ncol(cpu)), rescale, to = c(10, 100)) %>% #Scaling
  mutate_at(vars(2:ncol(cpu)), ~ ifelse(is.na(.), 0, .)) %>% #Na = 0
  select(-one_of("Model")) %>% #Pilih kolom benchmark
  as.matrix() %*% diag(c(5, 4, 4, 6, 6, 7, 7, 8, 8, 9,
                         9, 3, 3, 3, 3, 4, 5, 5, 5, 4, 
                         4, 4, 8, 7, 7, 6, 6, 6, 7, 7, 
                         8, 8, 9, 9, 6, 3, 4, 5, 5, 7)) %>%  #Beri bobot
  as.data.frame() %>% 
  mutate(Score = rowSums(across(where(is.numeric)))) %>% #Jumlahkan semua kolom
  # Bagi dengan jumlah kolom yang tidak sama dengan 0
  mutate(Score = Score / rowSums(across(where(is.numeric)) != 0)) %>% 
  mutate(Score = ifelse(is.na(Score), 0, Score)) %>% #NaN = 0
  select(one_of("Score"))  #Ambil kolom score aja
#Merge data ke cpu
cpu <- bind_cols(cpu %>% select(Model),  cpu.score %>% select(Score))
kable(head(cpu)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Model Score
AMD Ryzen Threadripper PRO 3995WX 391.9132
AMD Ryzen 9 7950X 460.4986
Intel Core i9-13900K 465.0502
AMD Ryzen 9 7950X3D 470.1593
AMD Ryzen 9 7900X 422.3929
Intel Core i7-13700K 413.5907

c1. Merge Data 1

Berikut algoritma untuk Merge atau Join data CPU Score dari cpu ke data .

Dalam pembuatan program-nya kami menggunakan loop dan nested if. Mengapa tidak menggunakan dplyr? Percayalah. Kami sudah mecoba berbagai cara. Namun tidak ada function secepat ini. Ya wajar saja sebenarnya. Karena kami memiliki \(10,000\) data. Oleh karena itu kami, saya terutama menghabiskan sebagian besar waktu saya untuk membuat code yang cepat ini.

Namun ternyata algoritma diatas blm 100% benar. Penjelsan di @###Arsip

Ini fungsi untuk cek yang 100% mirip. Segala kesalahan penulisan disamakan. Jika yang memang tidak sama maka tidak akan dipaksa sama. Misalnya

install_load('data.table')
# Fungsi untuk mengganti karakter tidak terdeteksi dengan spasi
clean_name <- function(name) {
  # Mengganti karakter tidak terdeteksi dengan spasi
  cleaned_name <- gsub("[\\h\\v\\n\\r\\f\\p{C}]+", " ", name, perl = TRUE)
  # Menghapus spasi di awal dan akhir teks
  cleaned_name <- trimws(cleaned_name)
  return(cleaned_name)
}

# Fungsi untuk mengMergekan data berdasarkan Algoritma
join_and_score1.1 <- function(data, cpu) {
  #Buat Kolom baru, set sebagai NA
  data[, BestMatch := NA_character_]
  data[, `CPU Score` := NA_real_]
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `Model` di data `cpu`
  cpu$Model <- clean_name(gsub("PRO", "", cpu$Model, ignore.case = TRUE))
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `CPU` di data `data`
  data$CPU <- clean_name(gsub("PRO", "", data$CPU, ignore.case = TRUE))
  
  for (i in 1:nrow(data)) {
    #Ambil dan bersihkan kolom CPU pada data baris i
    current_cpu <- clean_name(data[i, CPU])
    
    #Cari Model yang sama dengan CPU pada data baris i
    matching_rows <- cpu[tolower(Model) == tolower(current_cpu)] #Lowercase
    
    #Jika sama 100%, maka gabung
    if (nrow(matching_rows) > 0) {
      #[1] artinya Jika lebih dari 2, ambil yang pertama
      data[i, `CPU Score` := matching_rows[1]$Score] 
      data[i, BestMatch := matching_rows[1]$Model]
    } 
  }
  return(data)
}

# MengMergekan data "cpu" ke "data" dengan kondisi yang dioptimalkan
setDT(data)  # Mengubah data.frame menjadi data.table
setDT(cpu)   # Mengubah data.frame cpu menjadi data.table

#Panggil fungsi
coba <- join_and_score1.1(data, cpu)

d. Cek NA

cat("Banyaknya Laptop dengan Score CPU yang NA :", sum(is.na(coba$`CPU Score`)))
## Banyaknya Laptop dengan Score CPU yang NA : 8

Cek CPU apa saja yang NA, dan berapa jumlahnya.

NA.CPU.Score <- coba %>%
  group_by(CPU) %>% 
  summarise(NA.CPU.Score = sum(is.na(`CPU Score`))) %>%
  filter(NA.CPU.Score > 0)
cat("Banyaknya CPU dng Score yang NA :", nrow(NA.CPU.Score))
## Banyaknya CPU dng Score yang NA : 5
kable(NA.CPU.Score) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
CPU NA.CPU.Score
AMD A4-9120e 1
AMD A9-9400 1
Apple M2 (10-core CPU) 3
Intel Core i3-10210Y 1
Intel Pentium 4417U 2

Jika kami ada waktu untuk mencari satu persatu. Maka kami akan input data CPU manual lagi.

Sebelum mendapatkan algoritma yang pas tentunya ada kisah betapa susahnya menyusun potongan kode tersebut. Berikut kisahnya.

Jadi saya masih mendapatkan banyak data NA Padahal sudah sebanyak \(1891\) data benchmark CPU yang sudah kami ambil dari website diatas yang mana merupakan website benchmark terlengkap yang ada.

Namun ternyata kebanyakan datanya itu bukan tidak ada, namun penamaan nya saja yang berbeda. Olehkarena itu kami pun langkah demi langkah menentukan kode yang tepat.

Kisah dimulai dari :

Jika saya cari pada sheet CPU, terlihat bahwa tidak ada CPU NA yang ditemukan.

Namun jika saya cari lagi pada website tadi, terlihat bahawa CPU yang dicari itu ada namun dengan nama yang sedikit berbeda. Ketika saya cari-cari di internet, telihat bahwa tidak ada hasil benchmark dari AMD Ryzen 5 5650U. Hanya ada AMD Ryzen 5 PRO 5650U . Karena itu, kami memutuskan untuk menganggap bahwa kedua CPU ini sama. Maka Algoritmanya perlu diperbaiki lagi.

Terlihat bahwa ada semacam titik yang digaris bawahi oleh oranye. Terdapat masalah karakter non-ASCII yang tidak terlihat seperti spasi biasa.

Sisa nya, CPU Apple Saya tidak menemukan nya di website tadi. Sehingga perlu mencari di internet dan menambahkan manual ke sheet CPU.

  • Apple M1 (10 Core CPU, 14 Core GPU) : cpu-monkey.com
    Karena kami kesulitan untuk mencari yang tanpa 14 Core GPU. Maka ya kami anggap sama saja. Karena ya pada dasarnya sama saja, bedanya ini ada tambahan 14 Core GPU.

  • Apple M2 (10-Core GPU) : notebookcheck.net & laptopmedia.com
    Memang aneh. Namun ternyata ketika saya cek di tempat sebelumnya memang tidak ada. Welp harus masukin manual memang.

  • Apple M2 (12-core CPU, 19-core GPU) : cpu-monkey.com

  • Apple M2 (8-core GPU) : cpu-monkey.com

Agar tidak memakan waktu yang lama. Kami mengetes per 1000 baris. Kami mencoba baris 1:1000 ternyata 0 NA. 1001:2000 juga NA.

Namun pada 7001:8000 ternyata ada missing data. Yakni

Setelah kami cek di website ternyata memang tidak ada. Terpaksa kami harus cari datanya di internet.

Lanjut pada 8001:9000 pun tidak ada yang NA

Ketika melewati itu maka akan ada error. Lalu kami perbaiki algoritma nya.

Hasilnya tidak ada lagi error. Namun ternyata tersisa 1 NA. Yakni

Kami pun mencari pada website, ternyata memang tidak ada. Dan Surprisingly ternyata memang tidak ada data benchmark nya di internet. Sehingga bisa jadi itu karena sangat tidak terkenal dan sangat butut, maka memang tidak pantas untuk di benchmark. Maka dari itu kami putuskan untuk memberikan nilai \(0\) pada CPU Intel Core i3-10210Y .

c2. Merge Data 2

Sedangkan ini fungsi untuk memaksa mencari yang paling sama. Karena keterbatasan waktu. Kami akan menggunakan fungsi in untuk penggabungan data.

# Fungsi untuk mencari model CPU yang paling mirip
find_similar <- function(target, data) {
  
  #adist untuk menghitung jarak (distance) antara target_gpu dan setiap model CPU
  distances <- adist(target, data$Model, 
  #untuk memungkinkan pencocokan parsial (hanya sebagian dari string yang cocok)
                     partial = TRUE, 
  #ase-insensitive, sehingga tidak memedulikan huruf besar atau kecil.
                     ignore.case = TRUE)
  #mencari indeks model dengan jarak terkecil (yang paling mirip) 
  best_match_index <- which.min(distances)
  best_match_model <- data$Model[best_match_index]
  return(best_match_model)
}

# Fungsi untuk mengMergekan data jika ada yang sama
join_and_score2.1 <- function(data, cpu) {
  #Buat Kolom baru, set sebagai NA
  data[, BestMatch := NA_character_]
  data[, `CPU Score` := NA_real_]
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `Model` di data `cpu`
  cpu$Model <- clean_name(cpu$Model)
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `CPU` di data `data`
  data$CPU <- clean_name(data$CPU)
  
  for (i in 1:nrow(data)) {
    #Ambil dan bersihkan kolom CPU pada data baris i
    current_cpu <- clean_name(data[i, CPU])
    
    #Cari Model yang sama dengan CPU pada data baris i
    matching_rows <- cpu[tolower(Model) == tolower(current_cpu)] #Lowercase
    
    #Jika sama 100%, maka gabung
    if (nrow(matching_rows) > 0) {
      #[1] artinya Jika lebih dari 2, ambil yang pertama
      data[i, `CPU Score` := matching_rows[1]$Score] 
      data[i, BestMatch := matching_rows[1]$Model]
      
    #Jika tidak ada yang sama, maka cek kesamaan
    } else { 
      
      #Cari yang mirip dengan fungsi find_similar
      matching_rows <- cpu[cpu$Model == find_similar(current_cpu, cpu), ]
      
      #Jika ada yang mirip, maka gabung
        if (nrow(matching_rows) > 0) {
          #[1] artinya Jika lebih dari 2, ambil yang pertama
          data[i, `CPU Score` := matching_rows[1]$Score] 
          data[i, BestMatch := matching_rows[1]$Model]
          
        #Jika tidak ada yang sama, maka cek kesamaan
        }
      }
  }
  return(data)
}

# MengMergekan data "cpu" ke "data" dengan kondisi yang dioptimalkan
setDT(data)  # Mengubah data.frame menjadi data.table
setDT(cpu)   # Mengubah data.frame cpu menjadi data.table

#Panggil fungsi
data <- join_and_score2.1(data, cpu)
data <- data %>% select(-BestMatch)
kable(head(data)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB) Storage Score Display Score CPU Score
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284 20 4285.7143 32.40414 261.6019
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693 16 466.6667 25.98752 266.3142
Acer Predator Triton 300 Intel Core i7-11800H NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215 64 8571.4286 46.75460 264.7908
ASUS Vivobook 17X AMD Ryzen 7 5800H AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584 40 4285.7143 25.98752 256.4124
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247 12 2142.8571 25.98752 266.3142
Dell Vostro 7620 Intel Core i7-12700H NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177 24 1097.1429 30.13927 310.3157

Membuat CPU Score dari Intel Core i3-10210Y menjadi \(0\) .

data <- data %>%
  mutate(`CPU Score` = if_else(is.na(`CPU Score`), 0, `CPU Score`))

e. Brand Classification

Kami penasaran bagaimana sebaran dari brand CPU yang ada.

data <- data %>%
  mutate(`CPU Brand` = case_when(
    grepl("Intel", CPU) ~ "Intel",
    grepl("AMD", CPU) ~ "AMD",
    grepl("Apple", CPU) ~ "Apple",
    grepl("Mediatek", CPU) ~ "Mediatek",
    grepl("Qualcomm", CPU) ~ "Qualcomm",
    TRUE ~ "Other"
  ))
# Membuat bar chart persentase
ggplot(data = data %>% count(`CPU Brand`) %>% # banyaknya laptop brand x
                  mutate(perc = round(n / sum(n) * 100)), #buat persentase, 
       aes(x = reorder(`CPU Brand`, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 10, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "CPU Brand", y = "Persentase (%)", 
       title = "Sebaran Brand CPU Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 1)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, vjust =0.5,
                                  face = "bold", margin = margin(b = 50)),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

Terlihat bahwa brand CPU yang erbanyak adalah tim biru (intel), diikuti oleh tim merah (AMD). Dan kebetulan ada 1 CPU Brand Qualcomm ternyata. Sangat jarang.

f. Sebaran CPU Score

Sebaran CPU Score

install_load('ggridges','hrbrthemes','viridis')
ggplot(data, aes(x=`CPU Score`, y='')) + 
  #Violin
  geom_violin(scale="count", fill='purple3', color=NA, alpha=0.25, 
                    trim = FALSE) +
  #Boxplot
  geom_boxplot(fill='orange', color='black',
                     outlier.size=4, outlier.color='orange', 
                     alpha=0.7, notch=T, width=0.2) +
  #Mean Marker
  stat_summary(fun = mean, geom = "point", shape = 16, size = 4, color = "cyan3") +
  #COLORING
  scale_fill_viridis(alpha = 0.75, #Opacity
                     begin = 0.1, #Color pallte scale begins
                     end = 0.9, #Color pallte scale ends
                     direction = -1, #Flip color scale
                     discrete = T, #Discrete Value
                     option = "D") + #Color Palette
  theme_modern_rc(axis_title_just = "center", base_size = 15, 
                  axis_title_size = 25, plot_title_size = 30) +
  theme(plot.title = element_text(hjust=0.5),legend.position = "none") +
  labs(x = "\nCPU Score", y="", 
       title = "Sebaran CPU Score")

Jika melihat pada violin plot nya, terlihat bahwa sebarannya memiliki trimodal, atau 3 puncak. Dengan median atau nilai tengahnya yang hampir berada di tengah atau sekitar yang terlihat pada \(260\) Score. Nilai itu berdekatan dengan nilai Mean nya yang ditandai dengan warna biru muda. Dari boxplotnya saja memang terlihat berpusat pada nilai tengahnya. Namun berkat adanya violin plot, kita dapat melihat bahwa ini merupakan trimodal distribution.

Sebaran CPU Score Per Brand

install_load('ggridges','hrbrthemes','viridis')
ggplot(data, aes(x=`CPU Score`, y=`CPU Brand`, fill=`CPU Brand`)) + 
  geom_density_ridges() +
  #COLORING
  scale_fill_viridis(alpha = 0.75, #Opacity
                     begin = 0.1, #Color pallte scale begins
                     end = 0.9, #Color pallte scale ends
                     direction = -1, #Flip color scale
                     discrete = T, #Discrete Value
                     option = "D") + #Color Palette
  theme_modern_rc(axis_title_just = "center", base_size = 15, 
                  axis_title_size = 25, plot_title_size = 30) +
  theme(plot.title = element_text(hjust=0.5),legend.position = "none") +
  labs(x = "\nCPU Score",y = "Brand CPU\n", 
       title = "Sebaran CPU Score Per Brand")

Sedangkan jika berdasarkan brand nya. Sebaran nya seperti berikut.

7. Scoring GPU

Mirip seperti CPU lah pokoknya. Salah satu contoh benchmark GPU yang terkenal adalah 3DMARK.

3DMark adalah sebuah aplikasi benchmark yang digunakan untuk mengukur dan membandingkan kinerja komputer, khususnya dalam hal grafis dan gaming. Ini adalah salah satu alat yang paling populer digunakan oleh gamer, pengembang perangkat keras, dan pengguna komputer umum untuk menguji sejauh mana kemampuan grafis komputer mereka.

3DMark mencakup berbagai tes yang dirancang untuk mengukur berbagai aspek kinerja grafis, termasuk:

  1. Graphics Test: Ini mengukur kemampuan kartu grafis dalam menghasilkan grafik yang rumit dan berkinerja tinggi dalam permainan 3D. Grafik yang lebih baik, seperti tekstur, efek cahaya, bayangan, dan partikel, digunakan dalam pengujian ini untuk memeriksa kemampuan kartu grafis.

  2. Physics Test: Ini mengukur seberapa baik CPU dan GPU bekerja bersama dalam mengelola fisika simulasi dalam permainan. Ini mencakup simulasi pergerakan benda, tabrakan, dan lainnya.

  3. Combined Test: Ini adalah kombinasi dari tes grafis dan fisik untuk mengukur kinerja total sistem saat menjalankan permainan 3D yang intensif.

  4. Time Spy (DX12) dan Fire Strike (DX11): Ini adalah dua benchmark yang populer yang mendukung teknologi grafis DirectX 12 dan DirectX 11. Mereka menguji kemampuan komputer Anda dalam menjalankan game yang sesuai dengan teknologi tersebut.

Hasil benchmark 3DMark digunakan untuk membandingkan komputer atau kartu grafis berbeda dalam hal kinerja grafis. Semakin tinggi skor yang diperoleh dalam tes 3DMark, semakin baik kemampuan grafis komputer tersebut. Selain itu, hasil benchmark juga dapat digunakan untuk menentukan apakah komputer Anda mampu menjalankan permainan tertentu dengan baik atau memerlukan peningkatan perangkat keras.

Kami membuat Score untuk GPU dengan data benchmark dari website notebookcheck.net Dengan setting :

Agar perhitungannya maksimal dan presisi, kami menggunakan seluruh benchmark yang ada, yakni sebanyak \(24\) data benchmark.

Berikut Metode kami :

  1. Scaling data benchmark
    Agar nilai setiap benchmark berada dalam skala yang sama (10 sampai 100)

  2. Mengubah data NA menjadi \(0\)
    Not Available atau Data yang tidak ada harus diubah menjadi \(0\) Agar dapat dijumlahkan.

  3. Memberi Bobot pada setiap Benchmark
    Chat GPT memberi saran untuk nilai bobot masing-masing :

    Dengan cara perkalian matriks antara data benchmark \((\mathbf{B})\) dengan matriks diagonal bobot \((\mathbf{D})\):

    \[ \mathbf{B}_{n\times24} \boldsymbol{\cdot} \mathbf{D}_{24\times24} \]
    dimana \(n=\) Banyaknya baris data

    \[ \begin{pmatrix} b_{1.1} & b_{1.2} & \cdots & b_{1.11}\\ \vdots & \vdots & \vdots & \vdots \\ b_{n.1} & b_{n.2} & \cdots & b_{n.11}\\ \end{pmatrix} \boldsymbol{\cdot} \begin{pmatrix} 1 & 0 & 0 & \cdots & 0 \\ 0 & 2 & 0 & \cdots & 0 \\ 0 & 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 1 \end{pmatrix} \]

  4. Menjumlahkan Total Score dari masing-masing Benchmark
    Menggunakan rowSums()

  5. Membagi nya dengan banyaknya Benchmark yang bukan \(0\) atau NA
    Agar adil
    harus dibagi. Jadi mirip seperti rata-rata. Namun bedanya jika kolom Bechmark A = \(0\). Maka tidak akan dibagi. Misalnya :
    Benchmark A : NA
    Benchmark B : NA
    Benchmark C : \(1405\)
    Benchmark D : \(3329\)

    Score : \(\frac{A + B + C + D}{not.NA.nor.0}\) Score : \(\frac{0 + 0 + 1405 + 3329}{0+0+1+1}\)
    Score : \(2367\)
    Sehingga akan diperoleh hasil yang ADIL

  6. Mengubah NaN menjadi \(0\)
    Tak lupa untuk mengubah Not a Number menjadi \(0\). Ini dihasilkan ketika satu baris \(0\) semua

a. Seleksi Data

#Data Benchmark GPU
gpu <- read_xlsx("data_new.xlsx", sheet="GPU") %>%
       select(1, 18:ncol(.)) %>% #Ambil data benchmark nya saja 
  #Hapus selain numerik dan setelahnya, lalu Ubah jadi numerik
  mutate_at(vars(-1), ~as.numeric(gsub("[^0-9.].*$", "", .))) 
cat("Jumlah Baris:", nrow(gpu), "\n")
## Jumlah Baris: 1155
kable(head(gpu)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Model 3DMark Ice Storm GPU 3DMark Cloud Gate Standard Score 3DMark Cloud Gate GPU 3DMark11 P 3DMark11 P GPU 3DMark Fire Strike Score 3DMark Fire Strike Graphics 3DMark Time Spy Score 3DMark Time Spy Graphics 3DMark Vantage P 3DMark06 3DMark01 GFXBench GFXBench 3.0 1080p Manhattan Offscreen GFXBench 3.1 Manhattan ES 3.1 Offscreen Basemark GPU 1.2 Vulkan Medium Offscreen Basemark X 1.1 Medium Quality Basemark X 1.1 High Quality Unigine Heaven 3.0 DX 11, Normal Tessellation, High Shaders Unigine Valley 1.0 Extreme HD DirectX Cinebench R15 OpenGL 64Bit Cinebench R10 32Bit OpenGL ComputeMark v2.1 Normal, Score LuxMark v2.0 64Bit Sala GPUs-only
NVIDIA GeForce RTX 4090 785081 85474 250667 62922.0 104876.0 52791.0 77224.0 30977 36252 134128 62809.5 NA NA NA NA 104.6 NA NA NA 273.50 321.25 6836 91662.0 27320
AMD Radeon RX 7900 XTX 738814 87175 250728 53057.0 80793.5 51397.0 66967.0 26641 29699 147286 66523.0 NA NA NA NA NA NA NA NA 264.50 NA NA 62963.0 15019
NVIDIA GeForce RTX 4080 792455 88122 229762 59915.0 87222.0 48677.5 62041.5 25883 27962 143194 68851.0 NA NA NA NA NA NA NA NA 267.25 NA NA 62736.5 24322
NVIDIA GeForce RTX 3090 Ti 564087 75753 246319 49471.0 69481.0 36563.0 53110.0 19241 21645 NA NA NA NA NA NA NA NA NA NA 201.70 204.00 NA 52258.0 16046
AMD Radeon RX 7900 XT 737404 87173 259707 51605.5 75896.0 50669.0 63712.0 24042 25874 142489 66879.0 NA NA NA NA NA NA NA NA 243.30 NA NA 57570.0 13489
NVIDIA GeForce RTX 4070 Ti 815367 86974 217200 56052.0 75612.0 42591.0 53360.0 22481 22949 135624 66971.5 NA NA NA NA 104.6 NA NA NA 216.75 NA NA 51725.5 19289

b. Scoring

gpu.score <- gpu %>%
  mutate_at(vars(2:ncol(gpu)), rescale, to = c(10, 100)) %>% #Scaling
  mutate_at(vars(2:ncol(gpu)), ~ ifelse(is.na(.), 0, .)) %>% #Na = 0
  select(-one_of("Model")) %>% #Pilih kolom benchmark
  as.matrix() %*% diag(c(1, 2, 1, 1, 1, 3, 2, 3,
                         2, 1, 1, 2, 1, 2, 3, 2, 
                         3, 2, 2, 2, 2, 1, 2, 2)) %>%  #Beri bobot
  as.data.frame() %>% 
  mutate(Score = rowSums(across(where(is.numeric)))) %>% #Jumlahkan semua kolom
  # Bagi dengan jumlah kolom yang tidak sama dengan 0
  mutate(Score = Score / rowSums(across(where(is.numeric)) != 0)) %>% 
  mutate(Score = ifelse(is.na(Score), 0, Score)) %>% #NaN = 0
  select(one_of("Score"))  #Ambil kolom score aja
#Merge data ke cpu
gpu <- bind_cols(gpu %>% select(Model),  gpu.score %>% select(Score))
kable(head(gpu)) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
Model Score
NVIDIA GeForce RTX 4090 137.0597
AMD Radeon RX 7900 XTX 132.6856
NVIDIA GeForce RTX 4080 133.2037
NVIDIA GeForce RTX 3090 Ti 116.7809
AMD Radeon RX 7900 XT 126.9067
NVIDIA GeForce RTX 4070 Ti 114.3900

c1. Merge Data 1

Agak disayangkan, kami blm berhasil membuat fungsi join_and_score bisa digunakan untuk data gpu juga. Tapi tidak apa, kami hanya perlu mengganti cpu ke gpu. Sama seperti sebelumnya, kami kekurangan waktu.

Ini fungsi yang 100% sama.

# Fungsi untuk mengMergekan data berdasarkan Algoritma
join_and_score1.2 <- function(data, gpu) {
  #Buat Kolom baru, set sebagai NA
  data[, BestMatch := NA_character_]
  data[, `GPU Score` := NA_real_]
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `Model` di data `gpu`
  gpu$Model <- clean_name(gsub("PRO", "", gpu$Model, ignore.case = TRUE))
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `GPU` di data `data`
  data$GPU <- clean_name(gsub("PRO", "", data$GPU, ignore.case = TRUE))
  
  for (i in 1:nrow(data)) {
    #Ambil dan bersihkan kolom GPU pada data baris i
    current_gpu <- clean_name(data[i, GPU])
    
    #Cari Model yang sama dengan GPU pada data baris i
    matching_rows <- gpu[tolower(Model) == tolower(current_gpu)] #Lowercase
    
    #Jika sama 100%, maka gabung
    if (nrow(matching_rows) > 0) {
      #[1] artinya Jika lebih dari 2, ambil yang pertama
      data[i, `GPU Score` := matching_rows[1]$Score] 
      data[i, BestMatch := matching_rows[1]$Model]
    } 
  }
  return(data)
}

# MengMergekan data "gpu" ke "data" dengan kondisi yang dioptimalkan
setDT(data)  # Mengubah data.frame menjadi data.table
setDT(gpu)   # Mengubah data.frame gpu menjadi data.table

#Panggil fungsi
coba <- join_and_score1.2(data, gpu)

d. Cek NA

cat("Banyaknya Laptop dengan Score GPU yang NA :", sum(is.na(coba$`GPU Score`)))
## Banyaknya Laptop dengan Score GPU yang NA : 8809

Agak gila ya dari \(10,000\) data hanya \(11.91 \%\) data yang tidak NA.

Cek GPU apa saja yang NA, dan berapa jumlahnya.

NA.GPU.Score <- coba %>%
  group_by(GPU) %>% 
  summarise(NA.GPU.Score = sum(is.na(`GPU Score`))) %>%
  filter(NA.GPU.Score > 0)
cat("Banyaknya GPU dng Score yang NA :", nrow(NA.GPU.Score))
## Banyaknya GPU dng Score yang NA : 218
kable(NA.GPU.Score) %>% kable_styling(bootstrap_options = "striped", full_width = FALSE)
GPU NA.GPU.Score
AMD Fire W5130M (2GB GDDR5) 1
AMD Radeon 530 (2GB DDR3) 2
AMD Radeon 530 (2GB GDDR5) 1
AMD Radeon R2 1
AMD Radeon R3 (Beema) 1
AMD Radeon R4 10
AMD Radeon R5 (Carrizo-L) 1
AMD Radeon R7 M370 (2GB GDDR5) 1
AMD Radeon R7 M440 (4GB DDR3) 1
AMD Radeon R7 M445 (2GB GDDR5) 1
AMD Radeon R9 M275 (2GB GDDR5) 3
AMD Radeon RX Vega 6 (R2000/3000, 15W) 28
AMD Radeon RX Vega 6 (R4000/5000, 15W) 109
AMD Radeon RX Vega 6 (R4000/5000, 35/45W) 8
AMD Radeon RX Vega 7 (R4000/5000, 15W) 343
AMD Radeon RX Vega 7 (R4000/5000, 35/45W) 36
AMD Radeon RX Vega 8 (R2000/3000, 15W) 60
AMD Radeon RX Vega 8 (R4000/5000, 15W) 487
AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 39
AMD Radeon RX Vega M GL (Vega 870, 4GB HBM2) 1
AMD Radeon Vega 9 1
AMD Radeon WX 3200 (4GB GDDR5) 1
AMD Radeon WX 4150 (4GB GDDR5) 2
Apple M1 GPU (16-core) 2
Apple M1 GPU (7-core) 1
Apple M1 GPU (8-core) 1
Apple M1 Max GPU (32-core) 2
Apple M2 GPU 9
Apple M2 GPU (10-core) 14
Apple M2 GPU (8-core) 4
Apple M2 Max GPU 4
Imagination PowerVR GX6250 3
Intel HD Graphics 500 (Apollo Lake) 22
Intel HD Graphics 505 (Apollo Lake) 2
Intel Iris Plus Graphics G4 4
Intel Iris Plus Graphics G7 31
Intel Iris Xe Graphics G4 17
Intel Iris Xe Graphics G7 (64EU) 1
Intel Iris Xe Graphics G7 (80EU) 1249
Intel Iris Xe Graphics G7 (96EU) 1576
Intel UHD Graphics 135
Intel UHD Graphics (Alder Lake, 64EU) 60
Intel UHD Graphics G1 163
Intel UHD Graphics Xe (24EU) 5
Intel UHD Graphics Xe 750 (32EU) 12
Intel UHD Graphics Xe G4 (48EU) 438
Intel UHD Graphics Xe G4 (Tiger Lake, 48EU) 1
NVIDIA GeForce 940M (1GB GDDR5) 1
NVIDIA GeForce 940M (2GB DDR3) 2
NVIDIA GeForce 940MX (2GB DDR3) 1
NVIDIA GeForce 940MX (2GB GDDR5) 4
NVIDIA GeForce 940MX (4GB DDR3) 1
NVIDIA GeForce 940MX (4GB GDDR5) 1
NVIDIA GeForce GTX 1050 (2GB GDDR5) 3
NVIDIA GeForce GTX 1050 (3GB GDDR5) 2
NVIDIA GeForce GTX 1050 (4GB GDDR5) 4
NVIDIA GeForce GTX 1050 Ti (4GB GDDR5) 5
NVIDIA GeForce GTX 1050 Ti Max-Q (4GB GDDR5) 1
NVIDIA GeForce GTX 1060 (3GB GDDR5) 1
NVIDIA GeForce GTX 1060 (6GB GDDR5) 9
NVIDIA GeForce GTX 1060 Max-Q (6GB GDDR5) 2
NVIDIA GeForce GTX 1070 (8GB GDDR5) 1
NVIDIA GeForce GTX 1070 Max-Q (8GB GDDR5) 1
NVIDIA GeForce GTX 1650 (Laptop) 148
NVIDIA GeForce GTX 1650 (Laptop, 40W) 57
NVIDIA GeForce GTX 1650 (Laptop, 50W) 19
NVIDIA GeForce GTX 1650 Ti (Laptop) 17
NVIDIA GeForce GTX 1650 Ti (Laptop, 50W, 128-bit) 4
NVIDIA GeForce GTX 1660 Ti (Laptop) 21
NVIDIA GeForce GTX 860M (2GB GDDR5, GM107) 1
NVIDIA GeForce GTX 960M (4GB GDDR5) 1
NVIDIA GeForce GTX 965M (2GB GDDR5) 2
NVIDIA GeForce GTX 970M (3GB GDDR5) 1
NVIDIA GeForce MX130 (2GB GDDR5) 1
NVIDIA GeForce MX150 (2GB GDDR5) 5
NVIDIA GeForce MX250 (25W) 4
NVIDIA GeForce MX330 (2GB GDDR5, 25W) 2
NVIDIA GeForce MX330 (4GB GDDR5, 25W) 1
NVIDIA GeForce RTX 2050 8
NVIDIA GeForce RTX 2060 (Laptop) 10
NVIDIA GeForce RTX 2060 (Laptop, 80W) 3
NVIDIA GeForce RTX 2060 (Laptop, 90W) 4
NVIDIA GeForce RTX 2070 (Laptop) 4
NVIDIA GeForce RTX 2070 SUPER (Laptop) 4
NVIDIA GeForce RTX 2070 SUPER Max-Q (80W) 1
NVIDIA GeForce RTX 2080 SUPER (Laptop) 1
NVIDIA GeForce RTX 3050 (Laptop) 156
NVIDIA GeForce RTX 3050 (Laptop, 35W) 4
NVIDIA GeForce RTX 3050 (Laptop, 40W) 41
NVIDIA GeForce RTX 3050 (Laptop, 50W) 2
NVIDIA GeForce RTX 3050 (Laptop, 60W) 11
NVIDIA GeForce RTX 3050 (Laptop, 65W) 18
NVIDIA GeForce RTX 3050 (Laptop, 75W) 89
NVIDIA GeForce RTX 3050 (Laptop, 85W) 5
NVIDIA GeForce RTX 3050 (Laptop, 90W) 11
NVIDIA GeForce RTX 3050 (Laptop, 95W) 35
NVIDIA GeForce RTX 3050 Ti (Laptop) 166
NVIDIA GeForce RTX 3050 Ti (Laptop, 40W) 40
NVIDIA GeForce RTX 3050 Ti (Laptop, 50W) 19
NVIDIA GeForce RTX 3050 Ti (Laptop, 60W) 21
NVIDIA GeForce RTX 3050 Ti (Laptop, 65W) 2
NVIDIA GeForce RTX 3050 Ti (Laptop, 75W) 219
NVIDIA GeForce RTX 3050 Ti (Laptop, 85W) 5
NVIDIA GeForce RTX 3050 Ti (Laptop, 90W) 6
NVIDIA GeForce RTX 3050 Ti (Laptop, 95W) 33
NVIDIA GeForce RTX 3060 (Laptop) 117
NVIDIA GeForce RTX 3060 (Laptop, 105W) 140
NVIDIA GeForce RTX 3060 (Laptop, 115W) 4
NVIDIA GeForce RTX 3060 (Laptop, 120W) 41
NVIDIA GeForce RTX 3060 (Laptop, 125W) 31
NVIDIA GeForce RTX 3060 (Laptop, 130W) 81
NVIDIA GeForce RTX 3060 (Laptop, 140W) 104
NVIDIA GeForce RTX 3060 (Laptop, 65W) 4
NVIDIA GeForce RTX 3060 (Laptop, 70W) 2
NVIDIA GeForce RTX 3060 (Laptop, 75W) 55
NVIDIA GeForce RTX 3060 (Laptop, 80W) 15
NVIDIA GeForce RTX 3060 (Laptop, 85W) 5
NVIDIA GeForce RTX 3060 (Laptop, 90W) 8
NVIDIA GeForce RTX 3060 (Laptop, 95W) 19
NVIDIA GeForce RTX 3070 (Laptop) 5
NVIDIA GeForce RTX 3070 (Laptop, 100W) 12
NVIDIA GeForce RTX 3070 (Laptop, 105W) 60
NVIDIA GeForce RTX 3070 (Laptop, 110W) 32
NVIDIA GeForce RTX 3070 (Laptop, 130W) 38
NVIDIA GeForce RTX 3070 (Laptop, 140W) 24
NVIDIA GeForce RTX 3070 (Laptop, 85W) 11
NVIDIA GeForce RTX 3070 Ti (Laptop) 79
NVIDIA GeForce RTX 3070 Ti (Laptop, 105W) 89
NVIDIA GeForce RTX 3070 Ti (Laptop, 120W) 3
NVIDIA GeForce RTX 3070 Ti (Laptop, 130W) 73
NVIDIA GeForce RTX 3070 Ti (Laptop, 150W) 111
NVIDIA GeForce RTX 3080 (Laptop) 9
NVIDIA GeForce RTX 3080 (Laptop, 100W) 4
NVIDIA GeForce RTX 3080 (Laptop, 110W) 2
NVIDIA GeForce RTX 3080 (Laptop, 130W) 18
NVIDIA GeForce RTX 3080 (Laptop, 140W) 37
NVIDIA GeForce RTX 3080 (Laptop, 150W) 18
NVIDIA GeForce RTX 3080 (Laptop, 155W) 1
NVIDIA GeForce RTX 3080 (Laptop, 165W) 1
NVIDIA GeForce RTX 3080 (Laptop, 95W) 1
NVIDIA GeForce RTX 3080 Ti (Laptop) 30
NVIDIA GeForce RTX 3080 Ti (Laptop, 105W) 2
NVIDIA GeForce RTX 3080 Ti (Laptop, 150W) 22
NVIDIA GeForce RTX 3080 Ti (Laptop, 165W) 1
NVIDIA GeForce RTX 3080 Ti (Laptop, 175W) 34
NVIDIA GeForce RTX 4050 (Laptop) 30
NVIDIA GeForce RTX 4050 (Laptop, 105W) 5
NVIDIA GeForce RTX 4050 (Laptop, 120W) 16
NVIDIA GeForce RTX 4050 (Laptop, 140W) 62
NVIDIA GeForce RTX 4050 (Laptop, 45W) 68
NVIDIA GeForce RTX 4050 (Laptop, 65W) 2
NVIDIA GeForce RTX 4050 (Laptop, 85W) 2
NVIDIA GeForce RTX 4050 (Laptop, 95W) 1
NVIDIA GeForce RTX 4060 (Laptop) 92
NVIDIA GeForce RTX 4060 (Laptop, 105W) 22
NVIDIA GeForce RTX 4060 (Laptop, 115W) 2
NVIDIA GeForce RTX 4060 (Laptop, 120W) 5
NVIDIA GeForce RTX 4060 (Laptop, 125W) 9
NVIDIA GeForce RTX 4060 (Laptop, 130W) 3
NVIDIA GeForce RTX 4060 (Laptop, 140W) 204
NVIDIA GeForce RTX 4060 (Laptop, 45W) 74
NVIDIA GeForce RTX 4060 (Laptop, 55W) 1
NVIDIA GeForce RTX 4060 (Laptop, 90W) 4
NVIDIA GeForce RTX 4070 (Laptop) 49
NVIDIA GeForce RTX 4070 (Laptop, 105W) 93
NVIDIA GeForce RTX 4070 (Laptop, 125W) 14
NVIDIA GeForce RTX 4070 (Laptop, 130W) 5
NVIDIA GeForce RTX 4070 (Laptop, 140W) 74
NVIDIA GeForce RTX 4070 (Laptop, 60W) 3
NVIDIA GeForce RTX 4070 (Laptop, 90W) 3
NVIDIA GeForce RTX 4080 (Laptop) 8
NVIDIA GeForce RTX 4080 (Laptop, 105W) 1
NVIDIA GeForce RTX 4080 (Laptop, 125W) 8
NVIDIA GeForce RTX 4080 (Laptop, 145W) 6
NVIDIA GeForce RTX 4080 (Laptop, 150W) 1
NVIDIA GeForce RTX 4080 (Laptop, 165W) 1
NVIDIA GeForce RTX 4080 (Laptop, 175W) 51
NVIDIA GeForce RTX 4080 (Laptop, 60W) 3
NVIDIA GeForce RTX 4090 (Laptop) 22
NVIDIA GeForce RTX 4090 (Laptop, 105W) 3
NVIDIA GeForce RTX 4090 (Laptop, 125W) 4
NVIDIA GeForce RTX 4090 (Laptop, 165W) 3
NVIDIA GeForce RTX 4090 (Laptop, 175W) 62
NVIDIA Quadro M1000M (4GB GDDR5) 2
NVIDIA Quadro M1200 (4GB GDDR5) 1
NVIDIA Quadro M2000M (4GB GDDR5) 1
NVIDIA Quadro M5500 (8GB GDDR5) 1
NVIDIA Quadro M620 (2GB GDDR5) 3
NVIDIA Quadro P1000 (4GB GDDR5) 2
NVIDIA Quadro P2000 (Laptop, 4GB GDDR5) 2
NVIDIA Quadro P520 (4GB GDDR5) 3
NVIDIA Quadro P5200 (Laptop, 16GB GDDR5) 1
NVIDIA Quadro P600 (2GB GDDR5) 3
NVIDIA Quadro P600 (4GB GDDR5) 1
NVIDIA Quadro P620 (4GB GDDR5) 2
NVIDIA Quadro RTX 3000 (6GB GDDR6) 6
NVIDIA Quadro RTX 3000 Max-Q (6GB GDDR6) 1
NVIDIA Quadro RTX 4000 (8GB GDDR6) 1
NVIDIA Quadro RTX 4000 Max-Q (8GB GDDR6) 1
NVIDIA Quadro RTX 5000 (16GB GDDR6, Laptop) 1
NVIDIA Quadro RTX 5000 Max-Q (16GB GDDR6) 1
NVIDIA Quadro T1000 (4GB GDDR5) 4
NVIDIA Quadro T2000 (4GB GDDR5) 6
NVIDIA Quadro T500 63
NVIDIA Quadro T550 45
NVIDIA RTX 2000 Ada Generation 2
NVIDIA RTX 3000 Ada Generation 1
NVIDIA RTX 4000 Ada Generation 1
NVIDIA RTX 5000 Ada Generation 2
NVIDIA RTX A1000 (Laptop) 45
NVIDIA RTX A2000 (Laptop) 43
NVIDIA RTX A3000 (Laptop) 22
NVIDIA RTX A4000 (Laptop) 4
NVIDIA RTX A4500 (Laptop) 1
NVIDIA RTX A500 (Laptop) 3
NVIDIA RTX A5000 (Laptop) 20
NVIDIA RTX A5500 (Laptop) 1
NVIDIA T1200 19

Tapi walau begitu, ternyata hanya \(218\) jenis data GPU yang NA .

Jika kami ada waktu untuk mencari satu persatu. Maka kami akan input data GPU manual lagi.

c2. Merge Data 2

Sedangkan ini fungsi yang memaksa sama. (Mencari yang paling mirip)

# Fungsi untuk mengMergekan data jika ada yang sama
join_and_score2.2 <- function(data, gpu) {
  #Buat Kolom baru, set sebagai NA
  data[, BestMatch := NA_character_]
  data[, `GPU Score` := NA_real_]
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `Model` di data `gpu`
  gpu$Model <- clean_name(gsub("PRO", "", gpu$Model, ignore.case = TRUE))
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `GPU` di data `data`
  data$GPU <- clean_name(gsub("PRO", "", data$GPU, ignore.case = TRUE))
  
  for (i in 1:nrow(data)) {
    #Ambil dan bersihkan kolom GPU pada data baris i
    current_gpu <- clean_name(data[i, GPU])
    
    #Cari Model yang sama dengan GPU pada data baris i
    matching_rows <- gpu[tolower(Model) == tolower(current_gpu)] #Lowercase
    
    #Jika sama 100%, maka gabung
    if (nrow(matching_rows) > 0) {
      #[1] artinya Jika lebih dari 2, ambil yang pertama
      data[i, `GPU Score` := matching_rows[1]$Score] 
      data[i, BestMatch := matching_rows[1]$Model]
      
    #Jika tidak ada yang sama, maka cek kesamaan
    } else { 
      
      #Cari yang mirip dengan fungsi find_similar
      matching_rows <- gpu[gpu$Model == find_similar(current_gpu, gpu), ]
      
      #Jika ada yang mirip, maka gabung
        if (nrow(matching_rows) > 0) {
          #[1] artinya Jika lebih dari 2, ambil yang pertama
          data[i, `GPU Score` := matching_rows[1]$Score] 
          data[i, BestMatch := matching_rows[1]$Model]
          
        #Jika tidak ada yang sama, maka cek kesamaan
        }
      }
  }
  return(data)
}

# MengMergekan data "gpu" ke "data" dengan kondisi yang dioptimalkan
setDT(data)  # Mengubah data.frame menjadi data.table
setDT(gpu)   # Mengubah data.frame gpu menjadi data.table

#Panggil fungsi
data <- join_and_score2.2(data, gpu)
data <- data %>% select(-BestMatch)
kable(head(data)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name CPU GPU Display Storage Brand Price (USD) Price (IDR) Ram (GB) Storage Score Display Score CPU Score CPU Brand GPU Score
Lenovo ThinkPad T14 Gen 2 AMD Ryzen 7 5850U AMD Radeon RX Vega 8 (R4000/5000, 15W) 14.0”, Full HD (1920 x 1080), IPS 2000GB SSD Lenovo 1469.99 22572284 20 4285.7143 32.40414 261.6019 AMD 33.45651
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB HDD HP 1119.00 17182693 16 466.6667 25.98752 266.3142 Intel 31.90220
Acer Predator Triton 300 Intel Core i7-11800H NVIDIA GeForce RTX 3060 (Laptop, 105W) 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 4000GB SSD Acer 2049.00 31463215 64 8571.4286 46.75460 264.7908 Intel 66.70069
ASUS Vivobook 17X AMD Ryzen 7 5800H AMD Radeon RX Vega 8 (R4000/5000, 35/45W) 17.3”, Full HD (1920 x 1080), IPS 2000GB SSD ASUS 969.99 14894584 40 4285.7143 25.98752 256.4124 AMD 33.45651
HP 17 Intel Core i5-1335U Intel Iris Xe Graphics G7 (80EU) 17.3”, Full HD (1920 x 1080), IPS 1000GB SSD HP 712.99 10948247 12 2142.8571 25.98752 266.3142 Intel 31.90220
Dell Vostro 7620 Intel Core i7-12700H NVIDIA GeForce RTX 3050 (Laptop) 16.0”, WUXGA (1920 x 1200), IPS 512GB SSD Dell 1579.00 24246177 24 1097.1429 30.13927 310.3157 Intel 76.65398

Data Benchmark GPU Imagination PowerVR GX6250 Memang tidak ada dalam website notebookcheck.net. Padahal website tersebut memiliki data terlengkap. Ini berarti, saking tidak terkenalnya GPU tersebut, dalam website yang lengkap saja tidak masuk. Tidak mungkin GPU yang memiliki Benchmark Score yang bagus tidak masuk kedalam website terserbut. Sehinggga kami memutuskan untuk memberi nilai 0 kepada GPU tersebut.

data <- data %>%
  mutate(`GPU Score` = ifelse(is.na(`GPU Score`), 0, `GPU Score`))

e. Brand Classification

Kami penasaran bagaimana sebaran dari brand CPU yang ada.

data <- data %>%
  mutate(`GPU Brand` = case_when(
    str_detect(GPU, "NVIDIA") ~ "NVIDIA",
    str_detect(GPU, "Intel") ~ "Intel",
    str_detect(GPU, "ARM") ~ "ARM",
    str_detect(GPU, "Imagination") ~ "Imagination",
    str_detect(GPU, "Qualcomm") ~ "Qualcomm",
    str_detect(GPU, "AMD") ~ "AMD",
    str_detect(GPU, "Apple") ~ "Apple",
    TRUE ~ "Unknown"  # Jika tidak ada yang cocok
  ))
# Membuat bar chart persentase
ggplot(data = data %>% count(`GPU Brand`) %>% # banyaknya laptop brand x
                  mutate(perc = round(n / sum(n) * 100)), #buat persentase, 
       aes(x = reorder(`GPU Brand`, -n), y = perc)) +
  geom_bar(stat = "identity", fill='#2D99AE') +
  geom_text(aes(label = prettyNum(n,big.mark = ",")
                ), vjust = -0.5, size = 10, col="orange4", 
            fontface = "bold") + # Tambahkan label
  labs(x = "GPU Brand", y = "Persentase (%)", 
       title = "Sebaran Brand GPU Laptop") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme_modern_rc(axis_title_just = "center", base_size = 25, 
                  axis_title_size = 30, plot_title_size = 35) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, 
                                   margin = margin(b = 1)),
        axis.text.y = element_text(vjust = .5, face = "bold", 
                                   margin = margin(l = 20)),
        plot.title = element_text(hjust = 0.5, vjust =0.5,
                                  face = "bold", margin = margin(b = 50)),
        text = element_text(size = 30),
        plot.subtitle = element_text(hjust = 0.5)
        ) 

f. Sebaran GPU Score

Sebaran GPU Score

install_load('ggridges','hrbrthemes','viridis')
ggplot(data, aes(x=`GPU Score`, y='')) + 
  #Violin
  geom_violin(scale="count", fill='purple3', color=NA, alpha=0.25, 
                    trim = FALSE) +
  #Boxplot
  geom_boxplot(fill='orange', color='black',
                     outlier.size=4, outlier.color='orange', 
                     alpha=0.7, notch=T, width=0.1) +
  #Mean Marker
  stat_summary(fun = mean, geom = "point", shape = 16, size = 4, color = "cyan3") +
  #COLORING
  scale_fill_viridis(alpha = 0.75, #Opacity
                     begin = 0.1, #Color pallte scale begins
                     end = 0.9, #Color pallte scale ends
                     direction = -1, #Flip color scale
                     discrete = T, #Discrete Value
                     option = "D") + #Color Palette
  theme_modern_rc(axis_title_just = "center", base_size = 15, 
                  axis_title_size = 25, plot_title_size = 30) +
  theme(plot.title = element_text(hjust=0.5),legend.position = "none") +
  labs(x = "\nGPU Score", y="", 
       title = "Sebaran GPU Score")

Sebaran GPU Score Per Brand

install_load('ggridges','hrbrthemes','viridis')
ggplot(data, aes(x=`GPU Score`, y=`GPU Brand`, fill=`GPU Brand`)) + 
  geom_density_ridges() +
  #COLORING
  scale_fill_viridis(alpha = 0.75, #Opacity
                     begin = 0.1, #Color pallte scale begins
                     end = 0.9, #Color pallte scale ends
                     direction = -1, #Flip color scale
                     discrete = T, #Discrete Value
                     option = "D") + #Color Palette
  theme_modern_rc(axis_title_just = "center", base_size = 15, 
                  axis_title_size = 25, plot_title_size = 30) +
  theme(plot.title = element_text(hjust=0.5),legend.position = "none") +
  labs(x = "\nGPU Score",y = "Brand GPU\n", 
       title = "Sebaran GPU Score Per Brand")

8. Finishing

Urutkan Kolom

data <- data %>%
  relocate(Name, Brand, `Price (USD)`, `Price (IDR)`, `Ram (GB)`, CPU, `CPU Brand`, 
           `CPU Score`, GPU, `GPU Brand`, `GPU Score`, Display, 
           `Display Score`, Storage, `Storage Score`)
kable(head(data)) %>% 
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Name Brand Price (USD) Price (IDR) Ram (GB) CPU CPU Brand CPU Score GPU GPU Brand GPU Score Display Display Score Storage Storage Score
Lenovo ThinkPad T14 Gen 2 Lenovo 1469.99 22572284 20 AMD Ryzen 7 5850U AMD 261.6019 AMD Radeon RX Vega 8 (R4000/5000, 15W) AMD 33.45651 14.0”, Full HD (1920 x 1080), IPS 32.40414 2000GB SSD 4285.7143
HP 17 HP 1119.00 17182693 16 Intel Core i5-1335U Intel 266.3142 Intel Iris Xe Graphics G7 (80EU) Intel 31.90220 17.3”, Full HD (1920 x 1080), IPS 25.98752 1000GB HDD 466.6667
Acer Predator Triton 300 Acer 2049.00 31463215 64 Intel Core i7-11800H Intel 264.7908 NVIDIA GeForce RTX 3060 (Laptop, 105W) NVIDIA 66.70069 15.6”, Full HD (1920 x 1080), 144 Hz, IPS 46.75460 4000GB SSD 8571.4286
ASUS Vivobook 17X ASUS 969.99 14894584 40 AMD Ryzen 7 5800H AMD 256.4124 AMD Radeon RX Vega 8 (R4000/5000, 35/45W) AMD 33.45651 17.3”, Full HD (1920 x 1080), IPS 25.98752 2000GB SSD 4285.7143
HP 17 HP 712.99 10948247 12 Intel Core i5-1335U Intel 266.3142 Intel Iris Xe Graphics G7 (80EU) Intel 31.90220 17.3”, Full HD (1920 x 1080), IPS 25.98752 1000GB SSD 2142.8571
Dell Vostro 7620 Dell 1579.00 24246177 24 Intel Core i7-12700H Intel 310.3157 NVIDIA GeForce RTX 3050 (Laptop) NVIDIA 76.65398 16.0”, WUXGA (1920 x 1200), IPS 30.13927 512GB SSD 1097.1429

Pisah data dengan kasus NA = 0

Pisah data regresi

reg.usd <- data %>% 
  select( "Price (USD)", "Brand" ,"Ram (GB)", "CPU Score", 
          "GPU Score","Display Score", "Storage Score")
reg.idr <- data %>% 
  select( "Price (IDR)", "Brand" ,"Ram (GB)", "CPU Score", 
          "GPU Score","Display Score", "Storage Score")

Export

install_load('openxlsx')
write.xlsx(list("Data" = data, "Regresi (USD)" = reg.usd, "Regresi (IDR)"=reg.idr), 
           file = "managed.xlsx")

Referensi

Arsip

# Fungsi untuk mengganti karakter tidak terdeteksi dengan spasi
clean_name <- function(name) {
  # Mengganti karakter tidak terdeteksi dengan spasi
  cleaned_name <- gsub("[\\h\\v\\n\\r\\f\\p{C}]+", " ", name, perl = TRUE)
  # Menghapus spasi di awal dan akhir teks
  cleaned_name <- trimws(cleaned_name)
  return(cleaned_name)
}

# Fungsi untuk mengMergekan data berdasarkan Algoritma
join_and_score <- function(data, cpu) {
  #Buat Kolom baru, set sebagai NA
  data[, BestMatch := NA_character_]
  data[, `CPU Score` := NA_real_]
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `Model` di data `cpu`
  cpu$Model <- clean_name(gsub("PRO", "", cpu$Model, ignore.case = TRUE))
  
  # Mengganti karakter tidak terdeteksi dengan spasi pada kolom `CPU` di data `data`
  data$CPU <- clean_name(gsub("PRO", "", data$CPU, ignore.case = TRUE))
  
  for (i in 1:nrow(data)) {
    #Ambil dan bersihkan kolom CPU pada data baris i
    current_cpu <- clean_name(data[i, CPU])
    
    #Cari Model yang sama dengan CPU pada data baris i
    matching_rows <- cpu[tolower(Model) == tolower(current_cpu)] #Lowercase
    
    #Jika sama 100%, maka gabung
    if (nrow(matching_rows) > 0) {
      #[1] artinya Jika lebih dari 2, ambil yang pertama
      data[i, `CPU Score` := matching_rows[1]$Score] 
      data[i, BestMatch := matching_rows[1]$Model]
      
    #Jika tidak ada yang sama, maka bersihkan
    } else { 
      
        #Cek CPU pada data apakah punya tanda kurung?
        if (grepl("\\(", current_cpu)) {
          
            #Cek apakah luar kurung nya mirip 90%?
            #Hapus tanda kurung & isinya
            current_cpu_no_parentheses <- gsub("\\([^)]+\\)", "", current_cpu)
            
            
            matching_rows <- cpu[stringdist::stringdist(
            #Cari Model tanpa tanda kurung yang mirip sekitar 90% 
            #dengan CPU data tanpa tanda kurung
                        tolower(gsub("\\([^)]+\\)", "", Model)), 
                        tolower(current_cpu_no_parentheses), 
                        method = "jw") >= 0.90 & 
            #Sekaligus cek apakah isi dalam tanda kurung keduanya
            #mirip 80%?
                        stringdist::stringdist(
                            tolower(gsub(".*?\\((.*?)\\).*", "\\1", Model)), 
                            tolower(gsub(".*?\\((.*?)\\).*", "\\1", current_cpu)), 
                            method = "jw") >= 0.80]
            
            #Jika Ya
            if (nrow(matching_rows) > 0){
                #Maka gabung
                data[i, `CPU Score` := matching_rows[1]$Score] 
                data[i, BestMatch := matching_rows[1]$Model]
            } 
            
        #Jika tidak ada tanda kurung
        #Cek apakah mirip 90%?
        } else {
          matching_rows <- cpu[stringdist::stringdist(tolower(Model), 
                                                tolower(current_cpu), 
                                                method = "jw") >= 0.9]
          
          #Jika mirip 90%
          if (nrow(matching_rows) > 0) {
            #Maka gabung
            data[i, `CPU Score` := matching_rows[1]$Score] 
            data[i, BestMatch := matching_rows[1]$Model]
          }
        }
      }
  }
  return(data)
}

# MengMergekan data "cpu" ke "data" dengan kondisi yang dioptimalkan
setDT(data)  # Mengubah data.frame menjadi data.table
setDT(cpu)   # Mengubah data.frame cpu menjadi data.table

#Panggil fungsi
coba <- join_and_score(data, cpu)

Ada 5 data yagn tidak sama. Ini berarti fungsi join_and_score1 & join_and_score2 belum \(100\%\) Tepat.

Saya salah, malahan ternyata yang belum tepat itu fungsi join_and_score. Ini bisa dilihat pada :

Kampi pun pasrah. Karena kerumitan antara asal tulis, salah tulis atau memang disengaja.. Kita tidak tahu. Contohnya pada Apple M2 (10-core CPU) dan Apple M2 (10-core GPU) jika memakai algoritma pertama tentu ini akan dianggap sama. Namun sebenarnya ini tidak sama. Karena 10-core yang dimaksud berbeda. Satu untuk CPU satunya untuk GPU. Tentu ini akan fatal jika di benchmark. Sehingga memang tidak ada cara lain selain cari data manual lagi. Namun untuk saat ini kita pakai fungsi join_and_score1 & join_and_score2 dahulu, karena keterbatasan waktu dan ide.

Arsipbawah