library(readr)
## Warning: package 'readr' was built under R version 4.1.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.1.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.1.3
library(openintro)
## Warning: package 'openintro' was built under R version 4.1.3
## Loading required package: airports
## Warning: package 'airports' was built under R version 4.1.3
## Loading required package: cherryblossom
## Warning: package 'cherryblossom' was built under R version 4.1.3
## Loading required package: usdata
## Warning: package 'usdata' was built under R version 4.1.3
cars <- read.csv("https://assets.datacamp.com/production/course_1796/datasets/cars04.csv")
comics <- read.csv("https://assets.datacamp.com/production/course_1796/datasets/comics.csv")
life <- read.csv("https://assets.datacamp.com/production/course_1796/datasets/life_exp_raw.csv")
####Exploring Categorical Data
# Print the first rows of the data
head(comics)
## name id align eye hair
## 1 Spider-Man (Peter Parker) Secret Good Hazel Eyes Brown Hair
## 2 Captain America (Steven Rogers) Public Good Blue Eyes White Hair
## 3 Wolverine (James \\"Logan\\" Howlett) Public Neutral Blue Eyes Black Hair
## 4 Iron Man (Anthony \\"Tony\\" Stark) Public Good Blue Eyes Black Hair
## 5 Thor (Thor Odinson) No Dual Good Blue Eyes Blond Hair
## 6 Benjamin Grimm (Earth-616) Public Good Blue Eyes No Hair
## gender gsm alive appearances first_appear publisher
## 1 Male <NA> Living Characters 4043 Aug-62 marvel
## 2 Male <NA> Living Characters 3360 Mar-41 marvel
## 3 Male <NA> Living Characters 3061 Oct-74 marvel
## 4 Male <NA> Living Characters 2961 Mar-63 marvel
## 5 Male <NA> Living Characters 2258 Nov-50 marvel
## 6 Male <NA> Living Characters 2255 Nov-61 marvel
Data Comics consists of 11 variables with 2 kinds of data types, character and integer. The gsm column shows quite a lot of missing value data
# Check levels of align
comics$align <- factor(comics$align)
levels(comics$align)
## [1] "Bad" "Good" "Neutral"
## [4] "Reformed Criminals"
Melalui output diatas dapat diketahui bahawa terdapat beberapa tipe karakter yaitu "Good", "Neutrral, "Bad", dan "Reformed Criminals.
# Check the levels of gender
comics$gender <- factor(comics$gender)
levels(comics$gender)
## [1] "Female" "Male" "Other"
Gender karakter yang terdapat pada data Comics terdiri dari 3 jenis yaitu female, male, dan other.
# Create a 2-way contingency table
table(comics$align, comics$gender)
##
## Female Male Other
## Bad 1573 7561 32
## Good 2490 4809 17
## Neutral 836 1799 17
## Reformed Criminals 1 2 0
1. Data di atas merupakn tabel kontingensi yang menunjukan kombinasi antar 2 variabel kategori, dalam hal ini dipakai untuk melihat kombinasi antara variabel gender dengan align
2. Data Comics meiliki 3 jenis gender yaitu female, male, dan other.
3. Data Comics memiliki 4 tipe sifat karakter yaitu bad, good, neutral, dan reformed criminals.
4. Dilihat dari gendernya, karakter laki-laki merupakan gender yang paling sering muncul baik itu pada tokoh yang bersifat bad, good, neutral, dan reformed criminals.
5. Tokoh karakter laki-laki paling banyak memiliki sifat bad, sedangkan tokoh perempuan paling sering muncul dengan sifat yang good.
6. Jumlah tokoh komik dengan sifat "reformed criminals" memiliki jumlah paling sedikit yakni hanya sebanyak 3 observasi.
# Load dplyr
# Print tab
tab <- table(comics$align, comics$gender)
tab
##
## Female Male Other
## Bad 1573 7561 32
## Good 2490 4809 17
## Neutral 836 1799 17
## Reformed Criminals 1 2 0
Dapat kita lihta bahwa "Reformed Criminals" memiliki kombinasi yang sangat kecil. Untuk itu, agar penelitian berfokus pada analisis, kita akan membuang observasi yang mengandung nilai "Reformed Criminals" pada kolom align.
# Remove align level
comics <- comics %>%
filter(align != 'Reformed Criminals') %>%
droplevels()
levels(comics$align)
## [1] "Bad" "Good" "Neutral"
Pada tahap ini kita telah berhasil menghapus nilai "Reformed Criminals" dari kolom align.
###Side-by-side barcharts
# Load ggplot2
# Create side-by-side barchart of gender by alignment
ggplot(comics, aes(x = align, fill = gender)) +
geom_bar(position = "dodge")
1. Tokoh dengan gender laki-laki paling sering muncul baik untuk sifat bad, good, maupun neutral.
2. Sebaliknya, tokoh dengan gender perempuan nampak berada di tengah-tengah untuk setiap sifat.
3. Jumlah karakter dengan sifat neutral nampak paling sedikit jika dibadingkan dengan sifat bad dan good.
# Create side-by-side barchart of alignment by gender
ggplot(comics, aes(x = gender, fill = align)) +
geom_bar(positio = "dodge") +
theme(axis.text.x = element_text(angle = 90))
Jika pada code sebelumnya yang merupakan pembading adalah kolom align, maka pada code selanjutnya yang dijadikan pembanding ialah kolom gender.
1. Tokoh perempuan paling banyak memerankan sifat baik(protagonis), sedangkan paling sedikit memerankan sifat netral
2. Tokoh laki-laki paling banyak memerankan sifat jahat (antagonis), sedangkan paling sedikit memerankan sifat netral.
3. Secara umum, terdapat sebuah hubungan / relasi antara gender dengan sifat tokoh karakter.
###– Bar chart interpretation
Among characters with “Neutral” alignment, males are the most common. In general, there is an association between gender and alignment. There are more male characters than female characters in this dataset.
###Counts vs. proportions
# simplify display format
options(scipen = 999, digits = 3)
## create table of counts
tbl_cnt <- table(comics$id, comics$align)
tbl_cnt
##
## Bad Good Neutral
## No Dual 474 647 390
## Public 2172 2930 965
## Secret 4493 2475 959
## Unknown 7 0 2
1. Jenis pembangian sifat saat ini telah tereduksi menjadi 3 jenis yaitu "Bad", "Good", dan " Neutral"
2. Jenis identitas (kolom id) terbagi menjadi 4 jenis yaitu "No Dual", "Public", "Secret", dan "Unknown"
3. Kombinasi antara id dengn align terbanyak ialah tokoh jahat(bad) dengan identitas(id) berdifat rahasia diikuti dengan kombinasi tokoh yang berkarakter baik umunya memiki identitas yang dikenal oleh publik.
4. Semua karakter yang bersifat baik memiliki status identitas yang jelas/diketahui
# Proportional table
# All values add up to 1
prop.table(tbl_cnt)
##
## Bad Good Neutral
## No Dual 0.030553 0.041704 0.025139
## Public 0.140003 0.188862 0.062202
## Secret 0.289609 0.159533 0.061815
## Unknown 0.000451 0.000000 0.000129
Output diatas menggambarkan tentang persebaran kombinasi dalam sebuat data set, sebagai contoh jumlah tokoh karakter yang memiliki siftat jahat(bad) dengan identitas rahasia memiliki persentase terbesar yaitu sekitar 28,9% diikuti dengan tokoh baik dengan identitas publik sebesar 18,8%, dan untuk peringkat ketiga didudukin oleh tokoh karakter baik dengan identitas rahasia.
sum(prop.table(tbl_cnt))
## [1] 1
Jumlah dari setiap angka pada tabel di atas bernilai 1. Untuk mendapatkan nilai tersebut ialah dengan membagi antara frekuensi kombinasi dengan jumlah keseluruhan frekuensi tabel tersebut.
# All rows add up to 1
prop.table(tbl_cnt, 1)
##
## Bad Good Neutral
## No Dual 0.314 0.428 0.258
## Public 0.358 0.483 0.159
## Secret 0.567 0.312 0.121
## Unknown 0.778 0.000 0.222
Untuk tabel kali ini, jumlah angka disetiap baris akan berjumlah 1. Dari tabel kontinegnsi tersebut didapatkan informasi sebagai berikut.
1. Tokoh karakter dengan identitas "No Dual" paling banyak bersifat baik (good)
2. Tokoh karakter dengan identitas "Public" paling banyak bersifat baik (good)
3. Tokoh karakter dengan identitas "Secret" paling banyak bersifat jahat (bad)
4. Tokoh karakter dengan identitas "Unkown" paling banyak bersifat jahat.
5. Tidak ada karakter dengan identitas "Unkown" bersifat baik
# Coluns add up to 1
prop.table(tbl_cnt, 2)
##
## Bad Good Neutral
## No Dual 0.066331 0.106907 0.168394
## Public 0.303946 0.484137 0.416667
## Secret 0.628743 0.408956 0.414076
## Unknown 0.000980 0.000000 0.000864
Untuk tabel ini, jumlah agka di setiap kolom adalah sama dengan 1.
1. Jumlah tokoh karakter jahat paling banyak memiliki identitas rahasia.
2. Jumlah tokoh karakter netral cukup memiliki nilai yang imbang antara beridentitas publik maupun rahasia.
3. Jumalah tokoh karakter baik paling banyak memiliki identitas publik.
ggplot(comics, aes(x = id, fill = align)) +
geom_bar(position = "fill") +
ylab("proportion")
Visualisasi diatas meruapakan perbandingan komposisi antara tokoh bersifat jahat, baik, dan netral di masing-masing identitas/id.
1. Pada identitas "No Dual", tokoh protagonis mencakup persentase yang paling tinggi, yakni mendekati 50% dari total keseluruhan tokoh dengan identitas "No Dual".
2. Pada identitas "Public", tokoh protagonis mencakup persentase paling tinggi, yakni mendekati 50% dari total keseluruhan tokoh dengan identitas "Public".
3. Pada identitas "Secret", lebih dari setengah total keseluruhan tokoh dengan identitas "Secret" bersifat sebagai antagonis.
4. Pada identitas 'Unknown", tokoh antagonis mencakup persentase paling tinggi, yakni lebih 75% dari total keseluruhan tokoh dengan identitas "Unknown".
5. Obervasi dengan identitas kosong (NA) paling banyak berasal dari tokoh antagonis dengan persentase lebih dari 50% dari total keseluruhan tokoh dengan identitas kosong(NA).
ggplot(comics, aes(x = align, fill = id)) +
geom_bar(position = "fill") +
ylab("proportion")
1. Tokoh dengan sifat jahat(antagonis) cenderung memiliki identitas secret.
2. Tokoh dengan sifat netral cenderung untuk memiliki identitas public atau secret.
3. Tokoh dengan sifat baik(protagonis) cenderung memiliki identitas public ataupun secret.
4. Ketiga sifat karakter cenderung untuk memilki identitas publik ataupun secret.
###– Conditional proportions
tab <- table(comics$align, comics$gender)
options(scipen = 999, digits = 3) # Print fewer digits
prop.table(tab) # Joint proportions
##
## Female Male Other
## Bad 0.082210 0.395160 0.001672
## Good 0.130135 0.251333 0.000888
## Neutral 0.043692 0.094021 0.000888
1. Kolom gender memiliki 3 nilai berbeda yaitu female, male, dan other.
2. Kolom align memiliki 3 nilai berbeda yaitu bad, neutral, dan good.
3. Sebanyak 39% dari keseluruhan, tokoh jahat diperankan oleh laki-laki
4. Sebanyak 9% dari keseluruhan, tokoh netral diperankan oleh laki-laki
5. Sebanyal 25% dari keseluruhan, tokoh baik diperangkan oleh laki-laki
6. Karakter paling banyak merupakan laki-laki bersifat antagonis.
prop.table(tab, 2)
##
## Female Male Other
## Bad 0.321 0.534 0.485
## Good 0.508 0.339 0.258
## Neutral 0.171 0.127 0.258
1. Tokoh perempuan banyak memainkan karakter protagonis
2. Tokoh laki-laki banyak memainkan karakter antagonis
3. Tokoh yang bukan berender laki-laki maupun perempuan banyak memainkan karakter antagonis.
Approximately what proportion of all female characters are good? 51%
###– Counts vs. proportions (2)
# Plot of gender by align
ggplot(comics, aes(x = align, fill = gender)) +
geom_bar()
Berdasarkan sifatnya:
1. Lebih dari 50% pemain karakter jahat memiliki gender laki-laki, dengan jumlah lebih dari 7500 observasi.
2. Karakter netral lebih banyak dimakinkan oleh laki-laki ketimbang perempuan dengan jumlah kurang lebih 2000
3. Karkter baik dimainkan oleh sekitar 5000 tokoh laki-laki
4. Tokoh laki-laki lebih banyak dibandingan dengan permpuan, other, dan NA.
# Plot proportion of gender, conditional on align
ggplot(comics, aes(x = align, fill = gender)) +
geom_bar(position = "fill")
1. Persentase pemain laki-laki selalu lebih besar ketimbang gender lainnya.
2. Persentase pemain laki-laki selalu bernilai > 50% dari total masing-masing align.
3. Pemain bergender perempuan selalu menempati posisi kedua setelah laki-laki.
###Distribution of one variable
# Can use table function on just one variable
# This is called a marginal distribution
table(comics$id)
##
## No Dual Public Secret Unknown
## 1511 6067 7927 9
Tabel juga dapat digunakan pada proses analisis univariate.
1. Secara umum, mayoritas tokoh memiliki identitas rahasia diikuti dengan identitas publik.
2. Identitas yang paling janrang dimiliki oleh suatu tokoh adalah identitas "Unknown", persentasenya hanya sebesar 9/15514 = 0,00058.
3. Angka 15514 dari 19856 menyatakan bahwa kolom id memiliki nilai missing value.
# Simple barchart
ggplot(comics, aes(x = id)) +
geom_bar()
Code diatas merupakan visualisasi dari code sebelumnya, jumlah frekuensdi untuk setiap nilai pada kolom id.
1. Terlihat bahwa jumlah identitas yang paling banyak ialah "secret"
2. Sedangkan jumlah yang paling sedikit adalah unknown.
You can also facet to see variables indidually A little easier than filtering each and plotting. This is a rearrangement of the bar chart we plotted earlier We facte by alignment rather then coloring the stack. This can make it a little easier to answer some questions.
ggplot(comics, aes(x = id)) +
geom_bar() +
facet_wrap(~align)
Visualisasi diatas menunjukan jumlah komposisi antar 2 variabel kategori
1. Karakter antagonis(Bad) cenderung memiliki identitas rahasia.
2. Karakter netral(neutral) cenderung memiliki identitas publim maupun rahasia
3. Karakter protagonis(Good) cenderung memiliki identitas publik diikuti dengan identitas rahasia.
###– Marginal barchart It makes more sense to put neutral between Bad and Good We need to reorder the levels so it will chart this way Otherwise it will defult to alphabetical
# Change the order of the levels in align
comics$align <- factor(comics$align,
levels = c("Bad", "Neutral", "Good"))
# Create plot of align
ggplot(comics, aes(x = align)) +
geom_bar()
Diantara ketiga jenis nilai yang terketak pada kolom align, sebagian besar observasi memiliki tipe align bad diikuti dengan good dan neutral.
Observasi dengan align "Bad" berjumlah mendekati 10.000 (hampir lebih dari setengah) observasi.
###– Conditional barchart
# Plot of alignment broken down by gender
ggplot(comics, aes(x = align)) +
geom_bar() +
facet_wrap(~ gender)
1. Tokoh perempuan paling banyak memiliki peran sebagai tokoh baik, sebanyak lebih dari 2000 observasi.
2. Tokoh laki-laki palig banyak memiliki peran sebagai tokoh tidak baik dengan jumlah frekuensi sebanyak 8000 observasi.
3. Tokoh dengan gender selain perempuan dan laki-laki paling banyak memerankan tokoh tidak baik.
4. Tokoh dengan nilai kosong pada kolom gender paling banyak memerankan tokoh tidak baik.
5. Tokoh netral nampaknya memiliki jumlah observasi di keempat jenis nilai gender.
###– Improve piechart
# Put levels of flavor in decending order
pies <- data.frame(flavors = as.factor(rep(c("apple", "blueberry", "boston creme", "cherry", "key lime", "pumpkin", "strawberry"), times = c(17, 14, 15, 13, 16, 12, 11))))
lev <- c("apple", "key lime", "boston creme", "blueberry", "cherry", "pumpkin", "strawberry")
pies$flavor <- factor(pies$flavor, levels = lev)
head(pies$flavor)
## [1] apple apple apple apple apple apple
## Levels: apple key lime boston creme blueberry cherry pumpkin strawberry
# Create barchart of flavor
ggplot(pies, aes(x = flavor)) +
geom_bar(fill = "chartreuse") +
theme(axis.text.x = element_text(angle = 90))
1. Rasa yang paling banyak muncul ialah rasa apel.
2. Rasa yang paling sedikit muncul ialah rasa stroberi.
3. Seluruh rasa memiliki frekuensi diatas 10.
####Exploring Numerical Data
###Exploring numerical data
# A dot plot shows all the datapoints
ggplot(cars, aes(x = weight)) +
geom_dotplot(dotsize = 0.4)
## Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing non-finite values (stat_bindot).
# A histogram groups the points into bins so it does not get overwhelming
ggplot(cars, aes(x = weight)) +
geom_histogram(dotsize = 0.4, binwidth = 500)
## Warning: Ignoring unknown parameters: dotsize
## Warning: Removed 2 rows containing non-finite values (stat_bin).
# A density plot gives a bigger picture representation of the distribution
# It more helpful when there is a lot of data
ggplot(cars, aes(x = weight)) +
geom_density()
## Warning: Removed 2 rows containing non-finite values (stat_density).
1. Poin data weight banyak berada disekitar 2500 sampai 4000
2. Data cukup tersebar merata ditandai dengan betuk lonceng meskipun sedikit condong ke kiri.
3. Data condong kekanan menunjukan terjadi penumpukan data di sayap kiri
# A boxplot is a good way to just show the summary info of the distriubtion
ggplot(cars, aes(x = 1, y = weight)) +
geom_boxplot() +
coord_flip()
## Warning: Removed 2 rows containing non-finite values (stat_boxplot).
Dalam data set ini terlihat beberapa outliers ditandai dengan warna hitam berbentuk bulat di sebelah kanan. Dalam perhitungan boxplot, data dikatakan sebagai pencilan ketika memiliki berat diatas 5000. Nilai tertinggi mencapai sekitar 7000.
###– Faceted histogram
# Load package
library(ggplot2)
# Learn data structure
str(cars)
## 'data.frame': 428 obs. of 19 variables:
## $ name : chr "Chevrolet Aveo 4dr" "Chevrolet Aveo LS 4dr hatch" "Chevrolet Cavalier 2dr" "Chevrolet Cavalier 4dr" ...
## $ sports_car : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ suv : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ wagon : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ minivan : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ pickup : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ all_wheel : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ rear_wheel : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ msrp : int 11690 12585 14610 14810 16385 13670 15040 13270 13730 15460 ...
## $ dealer_cost: int 10965 11802 13697 13884 15357 12849 14086 12482 12906 14496 ...
## $ eng_size : num 1.6 1.6 2.2 2.2 2.2 2 2 2 2 2 ...
## $ ncyl : int 4 4 4 4 4 4 4 4 4 4 ...
## $ horsepwr : int 103 103 140 140 140 132 132 130 110 130 ...
## $ city_mpg : int 28 28 26 26 26 29 29 26 27 26 ...
## $ hwy_mpg : int 34 34 37 37 37 36 36 33 36 33 ...
## $ weight : int 2370 2348 2617 2676 2617 2581 2626 2612 2606 2606 ...
## $ wheel_base : int 98 98 104 104 104 105 105 103 103 103 ...
## $ length : int 167 153 183 183 183 174 174 168 168 168 ...
## $ width : int 66 66 69 68 69 67 67 67 67 67 ...
Data set "cars" terdiri dari 428 observasi dengan jumlah variabel sebanyak 19.
Kesembilan variabel terdiri dari 4 macam tipe data yaitu character yang dimiliki oleh variabel name, logical yang dimiliki oleh variabel sports_car, suv, wagon, minivan, pickup, all_wheel, dan rear_wheel. Variabel dengan tipe data integer dimiliki oleh variabel msrp, dealer_cost, ncyl, horsepwr, city_mpg, hwy_mpg, weight,wheel_base, length, dan with. Tipe data numeric hanya dimiliki oleh vaiabel eng_size.
Setiap variabel telah diberikan penamaan yang sesuai dengan maksudn variabel itu sendiri, hal ini adalah hal yang baik karena penamaan yang sesuai akan mempermudah analisis dan komputasi.
# Create faceted histogram
ggplot(cars, aes(x = city_mpg)) +
geom_histogram() +
facet_wrap(~ suv)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 14 rows containing non-finite values (stat_bin).
1. Mobil yang tidak memiliki suv cenderung untuk memiliki city mpg di sekitar 0 sampai 40
2. Mobil yang memiliki suv memiliki city mpg paling banyak sekitar 25.
###– Boxplots and density plots
unique(cars$ncyl)
## [1] 4 6 3 8 5 12 10 -1
Variabel ncyl dalam dataset cars memiliki 8 nilai berbeda.
table(cars$ncyl)
##
## -1 3 4 5 6 8 10 12
## 2 1 136 7 190 87 2 3
Berikut merupakan tabel frekuensi dari variabel ncyl. Kebanyak mobil memiki nycl antara 4, 6, atau 8.
# Filter cars with 4, 6, 8 cylinders
common_cyl <- filter(cars, ncyl %in% c(4,6,8))
# Create box plots of city mpg by ncyl
ggplot(common_cyl, aes(x = as.factor(ncyl), y = city_mpg)) +
geom_boxplot()
## Warning: Removed 11 rows containing non-finite values (stat_boxplot).
1. Mobil yang memiliki nycl 4 memiliki beberapa data point city_mpg yang tergolong sebagai pencilan. Nilai yang dikatakan sebagai pencilan ialah yang memiliki nilai city_mpg diatas sekitar 35
2, Mobil yan memiliki nycl nycl 6 memiliki 1 data poin yang tergolong sebagai pencilan, yaitu ketika nilai city_mpg nya bernilai dibawah sekitar 20.
3.Mobil yang dikelompok dengan nilai nycl 8 tidak memiliki pencilan berdasarkan nilai city_mpgnya
4. Rata-rata city_mpg disetiap jumlah nycl diatas 15
5. Rata-rata tertinggi dimiliki oleh kelompok nycl 4 diikuti kelompk nycl 6 dan 8.
# Create overlaid density plots for same data
ggplot(common_cyl, aes(x = city_mpg, fill = as.factor(ncyl))) +
geom_density(alpha = .3)
## Warning: Removed 11 rows containing non-finite values (stat_density).
Dari visualisasi diatas dapat dilihat bahwa belum ada kelompok ncyl yang terdistribusi normal. Hal ini ditandai degan bentuk lonceng yang cenderung condong.
Oleh sebab itu dapat diketahui bahwa persebaran data city_mpg berdasarkan pengelompokan nycl 4,6,8 masi kurang teserbar merata, meski pada ncyl 4 adalah bentuk yang paling mendekati lonceng (bell curved).
Mobil dengan ncyl 4 terlihat memiliki nilai city_mpg sekitar 20-30.
Mobil dengan 4 ssilinder memiliki nilai city_mpg yang lebih baik ktimbang mobil yang memiliki nilai silinder 6 ataupun 8
###– Compare distribution via plots The highest mileage cars have 4 cylinders. The typical 4 cylinder car gets better mileage than the typical 6 cylinder car, which gets better mileage than the typical 8 cylinder car. Most of the 4 cylinder cars get better mileage than even the most efficient 8 cylinder cars.
###Distribution of one variable ### Marginal and conditional histograms
# Create hist of horsepwr
cars %>%
ggplot(aes(horsepwr)) +
geom_histogram() +
ggtitle("Horsepower distribution")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Variabel horsepower belum dapat dikatakan terdistribusi normal sebab bentuk histogram yang belum menyerupai lonceng. Kebanyakan mobil dari observasi memili nilai horse power sekitar 150-250
Nilai horsepower tertinggi yang dimiliki seuah mobil dalam dataset ini adalah 500.
# Create hist of horsepwr for affordable cars
cars %>%
filter(msrp < 25000) %>%
ggplot(aes(horsepwr)) +
geom_histogram() +
xlim(c(90, 550)) +
ggtitle("Horsepower distribtion for msrp < 25000")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 1 rows containing non-finite values (stat_bin).
## Warning: Removed 2 rows containing missing values (geom_bar).
Mobil yang memiliki mrsp bibawah 2500 memiliki nilai horsepower di antara 100-250. Mayoritas observasi (mrsp<25000) memiliki nilai horsepower sekitar 120-180.
###– Marginal and conditional histograms interpretation The highest horsepower car in the less expensive range has just under 250 horsepower. ###– Three binwidths
# Create hist of horsepwr with binwidth of 3
cars %>%
ggplot(aes(horsepwr)) +
geom_histogram(binwidth = 3) +
ggtitle("binwidth = 3")
# Create hist of horsepwr with binwidth of 30
cars %>%
ggplot(aes(horsepwr)) +
geom_histogram(binwidth = 30) +
ggtitle("binwidth = 30")
# Create hist of horsepwr with binwidth of 60
cars %>%
ggplot(aes(horsepwr)) +
geom_histogram(binwidth = 60) +
ggtitle("binwidth = 60")
Dari visualisasi di atas yang hendak disampaikan ialah persebaran data. semakin besar nilai "ban width" maka akan terlihat memiliki nilai persebaran yang semakin merata.Sebaliknya semakin sedikit nilai bandwidth maka akan semakin akurat persebaran datanya.
Mayoritas data memiliki nilai horsepower sekitar 200-300.
####Box plots ###– Box plots for outliers
# Construct box plot of msrp
cars %>%
ggplot(aes(x = 1, y = msrp)) +
geom_boxplot()
Berdasarkan visualisai diatas dapat dilihat bahwa data memiliki beberapa pencilan. Yang di anggap sebagai pencilan pada data ini adalah nilai-nilai yang berasa di atas sekitar 70000
# Exclude outliers from data
cars_no_out <- cars %>%
filter(msrp < 100000)
# Construct box plot of msrp using the reduced dataset
cars_no_out %>%
ggplot(aes(x = 1, y = msrp)) +
geom_boxplot()
Setelah melakukan filterring pada data yang memiliki nilai mrsp lebih dari 100000, kita dapat melihat lebih jelas letak data point yang dikatakan sebagai pencilan, yakni disekitar 65000.
###– Plot selection
# Create plot of city_mpg
cars %>%
ggplot(aes(x = 1, y = city_mpg)) +
geom_boxplot()
## Warning: Removed 14 rows containing non-finite values (stat_boxplot).
Visualisasi di atas menunjukan pencilan yang terdapat pada variabel city_mpg. Berdasarkan prhitungan box plot, yang diidentifikasi sebagai pencilan ialah mereka yang memiliki nilai city_mpg sekitar 27 dan yang kurang dari sekitar 13.
cars %>%
ggplot(aes(city_mpg)) +
geom_density()
## Warning: Removed 14 rows containing non-finite values (stat_density).
Dari visualisasi diatas dapat dilihat bahwa persebaran data city_mpg masih belum sempurna, grafik masih berbentuk bel yang condong ke sebelah kiri. Mayoritas observasi memiliki nilai city mpg sekitar 15 sampai 20.
# Create plot of width
cars %>%
ggplot(aes(x = 1, y = width)) +
geom_boxplot()
## Warning: Removed 28 rows containing non-finite values (stat_boxplot).
Dari visualisasi diatas dapat diketahui bahwa variabel width memiliki nila pencilan, dimana yang dikatakan sebagai pencilan ialah mereka yang memiliki nilai sekitar 80 keatas.
Rata-rata lebar mobil iala sekitar 71.
cars %>%
ggplot(aes(x = width)) +
geom_density()
## Warning: Removed 28 rows containing non-finite values (stat_density).
Dari visualisasi diatas dapat dikaetahui bahwa variabel width belum cukup terdistribusi dengan baik.
Sebagian besar mobil memiliki lebar.width sekitar 67 hinggan 73 inch.
####Visualization in higher dimensions
###– 3 variable plot
# Facet hists using hwy mileage and ncyl
common_cyl %>%
ggplot(aes(x = hwy_mpg)) +
geom_histogram() +
facet_grid(ncyl ~ suv) +
ggtitle("hwy_mpg by ncyl and suv")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 11 rows containing non-finite values (stat_bin).
Plot diatas menujukan bahwa mobil tanpa suv dengan jumlah silinder 4 memiliki nilai hwy_mpg yang lebih baik ketimbang mereka yang tidak memiliki.
Mobil tanpa suv memiliki hwy_mpg yang lebih baik ketimbang mereka yang tidak memiliki suv.
Semakin banyak silinder maka semakin buruk nilai hwy_mpg yang didapat.
###-Interpret 3 var plot Across both SUVs and non-SUVs, mileage tends to decrease as the number of cylinders increases.
####Numerical Summaries
###Measures of center What is a typical value for life expectancy? We will look at just a few data points here And just the females
head(life)
## State County fips Year Female.life.expectancy..years.
## 1 Alabama Autauga County 1001 1985 77.0
## 2 Alabama Baldwin County 1003 1985 78.8
## 3 Alabama Barbour County 1005 1985 76.0
## 4 Alabama Bibb County 1007 1985 76.6
## 5 Alabama Blount County 1009 1985 78.9
## 6 Alabama Bullock County 1011 1985 75.1
## Female.life.expectancy..national..years.
## 1 77.8
## 2 77.8
## 3 77.8
## 4 77.8
## 5 77.8
## 6 77.8
## Female.life.expectancy..state..years. Male.life.expectancy..years.
## 1 76.9 68.1
## 2 76.9 71.1
## 3 76.9 66.8
## 4 76.9 67.3
## 5 76.9 70.6
## 6 76.9 66.6
## Male.life.expectancy..national..years. Male.life.expectancy..state..years.
## 1 70.8 69.1
## 2 70.8 69.1
## 3 70.8 69.1
## 4 70.8 69.1
## 5 70.8 69.1
## 6 70.8 69.1
x <- head(round(life$Female.life.expectancy..years.), 11)
x
## [1] 77 79 76 77 79 75 77 77 77 78 77
Dilakukan pembutakan untuk 11 observasi pertama pada variabel Female.life.expectancy..years.
mean
balance point of the data sensitive to extreme values
sum(x)/11
## [1] 77.2
mean(x)
## [1] 77.2
kedua kode di atas menghasilkan keluaran yang sama, hal ini berarti bahwa mean merupakan function dengan rumus jumlah n observasi dibagi dengan n.
median
middle value of the data robust to extreme values most approrpriate measure when working with skewed data
sort(x)
## [1] 75 76 77 77 77 77 77 77 78 79 79
median(x)
## [1] 77
Ketika kita ingin menghitung nilai median secara maual, kita dapat terlebih dahulu mengurutkan secara menaik baru memilih data ditengah. Atau kita juga dapat mencari median dengan bantuan function "median" itu sendiri.
table(x)
## x
## 75 76 77 78 79
## 1 1 6 1 2
Berikut merupakan tabel frekuensi dari data yang dimiliki. Modus dari data yang kita miliki adalah 77, yaitu berjumlah 6 data.
###– Calculate center measures
library(gapminder)
## Warning: package 'gapminder' was built under R version 4.1.3
str(gapminder)
## tibble [1,704 x 6] (S3: tbl_df/tbl/data.frame)
## $ country : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
## $ lifeExp : num [1:1704] 28.8 30.3 32 34 36.1 ...
## $ pop : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
## $ gdpPercap: num [1:1704] 779 821 853 836 740 ...
Data set gapminder terdiri dari 1704 observasi dengan 6 variabel.
Ke enam variabel ini terdiri dari 3 jenis yakni factor yang dimiliki oleh variabel country dan contingent, integer yang dimiliki oleh variabel year dan pop, serta, tipe data numeric untuk variabel lifeExp adn gdpPercap.
# Create dataset of 2007 data
gap2007 <- filter(gapminder, year == 2007)
# Compute groupwise mean and median lifeExp
gap2007 %>%
group_by(continent) %>%
summarize(mean(lifeExp),
median(lifeExp))
## # A tibble: 5 x 3
## continent `mean(lifeExp)` `median(lifeExp)`
## <fct> <dbl> <dbl>
## 1 Africa 54.8 52.9
## 2 Americas 73.6 72.9
## 3 Asia 70.7 72.4
## 4 Europe 77.6 78.6
## 5 Oceania 80.7 80.7
Mengelompokkan data yang berada pada tahun 2007, kemudian di kelompokkan berdasarkan kontinennya menurut mean dan mediannya.
# Generate box plots of lifeExp for each continent
gap2007 %>%
ggplot(aes(x = continent, y = lifeExp)) +
geom_boxplot()
1. Berdasarkan hasi visualisasi diatas dapat dilihat bahwa hanya benua America dan Asia saja ya yang memiliki outlier.
2. Rata-rata life expectancy tertinggi di pegang oleh benua oceania sedangkan rata-rata terendah dipengang oleh benua afrika.
####Measures of variability We wnat to know ‘How much is the data spread out from the middle?’ Just looking at the data gives us a sense of this But we want break it down to one number so we can compare sample distributions
x
## [1] 77 79 76 77 79 75 77 77 77 78 77
We could just take the differnce between all points and the mean and add it up But that would equal 0. Thats the idea of the mean.
# Look at the difference between each point and the mean
sum(x - mean(x))
## [1] -0.0000000000000568
So we can square the differnce But this number will keep getting bigger as you add more observations We want something that is stable
# Square each difference to get rid of negatives then sum
sum((x - mean(x))^2)
## [1] 13.6
Lagkah diatas merupakan cara untuk mencari nilai variasi secara manual
Variance
so we divide by n - 1 This is called the sample variance. One of the most useful measures of a sample distriution
sum((x - mean(x))^2)/(length(x) - 1)
## [1] 1.36
var(x)
## [1] 1.36
Kedua kode diatas merupakan cara untuk mencari variasi suatu data. Kode pertama menyatakan cara untuk mendapatkan variasi secara manual sedangkan kode pada bagian bawah menunjukan cara mencari variasi menggunakan function "var". Nilai varians yang didapatkan adalah sama yaitu 1,36
Standard Deviation
Another very useful metric is the sample standard deviation This is just the square root of the variance The nice thing about the std dev is that it is in the same units as the original data In this case its 1.17 years
sqrt(sum((x - mean(x))^2)/(length(x) - 1))
## [1] 1.17
sd(x)
## [1] 1.17
Kode diatas merupakan cara untuk mencari standari deviasi. Kode pertama menunjukan tentang bagaimana cara mencari standar deviasi secara manual sedangkan kode di bagian bawah digunakan untuk emncari standar deviasi dengan bantuan function "std". Nilai standar varians yang didapatkan adalan sama yaitu 1.17
Inter Quartile Range
The IQR is the middle 50% of the data The nice thing about this one is that it is not sensitve to extreme values All of the other measures listed here are sensitive to extreme values
summary(x)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 75.0 77.0 77.0 77.2 77.5 79.0
Kode ini menunjukan 5 atribut data yaitu nilai terkecil yaitu 75, kuartil bawah yaitu 77, nilai median yaitu 77, kuartil atas yaitu 77.2, dan nilai maximum yaitu 79.
Range
max and min are also interesting as is the range, or the difference between max and min
IQR(x)
## [1] 0.5
Merupakan selisih nilai antar kuartil atas - kuartil bawah.
max(x)
## [1] 79
min(x)
## [1] 75
diff(range(x))
## [1] 4
Range merupakan selisih dari nilai terbesar dikurang dengan nilai terkecil suatu data, dalam hal ini didapatkan rang/jangkauan sebesar 4.
Nilai maximum data adalah 79
Nili minimum data adalah 75
###– Calculate spread measures
str(gap2007)
## tibble [142 x 6] (S3: tbl_df/tbl/data.frame)
## $ country : Factor w/ 142 levels "Afghanistan",..: 1 2 3 4 5 6 7 8 9 10 ...
## $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 4 1 1 2 5 4 3 3 4 ...
## $ year : int [1:142] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
## $ lifeExp : num [1:142] 43.8 76.4 72.3 42.7 75.3 ...
## $ pop : int [1:142] 31889923 3600523 33333216 12420476 40301927 20434176 8199783 708573 150448339 10392226 ...
## $ gdpPercap: num [1:142] 975 5937 6223 4797 12779 ...
Dataset gap20007 terdiri dari 142 observasi dengan 6 variabel.
Ke enam variabel tersebut terdiri dari 3 jenis tipe data itu:
Tipe data factor deimiliki oleh variabel country dan continent
Tipe data integer dimiliki oleh variabel year dan pop
Tipe data numeric dimiliki oleh variabel lifeExp dan gdpPercapt
# Compute groupwise measures of spread
gap2007 %>%
group_by(continent) %>%
summarize(sd(lifeExp),
IQR(lifeExp),
n())
## # A tibble: 5 x 4
## continent `sd(lifeExp)` `IQR(lifeExp)` `n()`
## <fct> <dbl> <dbl> <int>
## 1 Africa 9.63 11.6 52
## 2 Americas 4.44 4.63 25
## 3 Asia 7.96 10.2 33
## 4 Europe 2.98 4.78 30
## 5 Oceania 0.729 0.516 2
Dari pengelompokan diatas dapat dikeathu bahwa pada tahun 2007:
1. Afrika memiliki 52 negara
2. America memiliki 25 negara
3. Asia memiliki 33 negara
4. Europe memiliki 30 negara
5. Oceania memiliki 2 negara.
Standar deviasi terkecil dimiliki oleh benua Oceania sedangkan terbesar oleh benua Africa
IQR terbesar dimiliki oleh benuai Africa sedangkan yang terkecil oleh benua Oceania.
# Generate overlaid density plots
gap2007 %>%
ggplot(aes(x = lifeExp, fill = continent)) +
geom_density(alpha = 0.3)
Dari visualisasi diatas dapat dilihat bahwa:
1. Nilai harapan hidup terendah dimiliki oleh benua Afrika dengan rentang 40 - 65
2. Rentang hidup tertinggi dimiliki oleh benua oceania yaitu sekitar 78 - 80 tahun
3. Sebagian besar harapan hidup benua America berada disekitar 70-80
4. Asia memiliki harapan hidup di sekitar 70-72 tahun
###– Choose measures for center and spread
# Compute stats for lifeExp in Americas
head(gap2007)
## # A tibble: 6 x 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Afghanistan Asia 2007 43.8 31889923 975.
## 2 Albania Europe 2007 76.4 3600523 5937.
## 3 Algeria Africa 2007 72.3 33333216 6223.
## 4 Angola Africa 2007 42.7 12420476 4797.
## 5 Argentina Americas 2007 75.3 40301927 12779.
## 6 Australia Oceania 2007 81.2 20434176 34435.
gap2007 %>%
filter(continent == "Americas") %>%
summarize(mean(lifeExp),
sd(lifeExp))
## # A tibble: 1 x 2
## `mean(lifeExp)` `sd(lifeExp)`
## <dbl> <dbl>
## 1 73.6 4.44
Pengelompokkan data pada tahun 2007 dalam benua America, hasilanya memiliki rata-rata hrapan hidup sekitar 73,6 dan stanar deviasi sebesar 4,44.
# Compute stats for population
gap2007 %>%
summarize(median(pop),
IQR(pop))
## # A tibble: 1 x 2
## `median(pop)` `IQR(pop)`
## <dbl> <dbl>
## 1 10517531 26702008.
Nilai median dari harapan hidup benua america adalah 10517531 dengna nilai IQR 26702008.
####Shape and transformations 4 chracteristics of a distribution that are of interest:
center already covered spread or variablity already covered shape modality: number of prominent humps (uni, bi, multi, or uniform - no humps) skew (right, left, or symetric) Can transform to fix skew outliers
###– Describe the shape
A: unimodal, left-skewed B: unimodal, symmetric C: unimodal, right-skewed D: bimodal, symmetric
###– Transformations
# Create density plot of old variable
gap2007 %>%
ggplot(aes(x = pop)) +
geom_density()
Dari visualisasi diatas dapat dilihat bahwa persebaran data pop kurang baik sebab bentuk grafik yang codong kekiri. Oleh karena itu kita akan menangani masalah ini pada baris kode selanjutnya.
# Transform the skewed pop variable
gap2007 <- gap2007 %>%
mutate(log_pop = log(pop))
# Create density plot of new variable
gap2007 %>%
ggplot(aes(x = log_pop)) +
geom_density()
Kini persebaran data pop sudah jauh lebih baik, bahkan sudah menyeryupai bentuk lonceng bell. Hal ini menandakan bahwa data sudah terdistribusi dengan baik/ berdistribusi normal.
####Outliers ###– Identify outliers
# Filter for Asia, add column indicating outliers
str(gapminder)
## tibble [1,704 x 6] (S3: tbl_df/tbl/data.frame)
## $ country : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
## $ lifeExp : num [1:1704] 28.8 30.3 32 34 36.1 ...
## $ pop : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
## $ gdpPercap: num [1:1704] 779 821 853 836 740 ...
gap_asia <- gap2007 %>%
filter(continent == "Asia") %>%
mutate(is_outlier = lifeExp < 50)
# Remove outliers, create box plot of lifeExp
gap_asia %>%
filter(!is_outlier) %>%
ggplot(aes(x = 1, y = lifeExp)) +
geom_boxplot()
Kini kita mengelompokkan data pada benua Asia di tahun 2007. Setelah di lakukan analisis pencilan menggunakan metoe boxplot, tidak ditemukan 1 pun pencilan. Nolai rata-rata harapan hidup benua asia berkisar 73-74 tahun.
####Case Study ####Introducing the data ###– Spam and num_char
# ggplot2, dplyr, and openintro are loaded
# Compute summary statistics
email %>%
group_by(spam) %>%
summarize(
median(num_char),
IQR(num_char))
## # A tibble: 2 x 3
## spam `median(num_char)` `IQR(num_char)`
## <fct> <dbl> <dbl>
## 1 0 6.83 13.6
## 2 1 1.05 2.82
str(email)
## tibble [3,921 x 21] (S3: tbl_df/tbl/data.frame)
## $ spam : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
## $ to_multiple : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 2 2 1 1 ...
## $ from : Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
## $ cc : int [1:3921] 0 0 0 0 0 0 0 1 0 0 ...
## $ sent_email : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 2 2 1 1 ...
## $ time : POSIXct[1:3921], format: "2012-01-01 13:16:41" "2012-01-01 14:03:59" ...
## $ image : num [1:3921] 0 0 0 0 0 0 0 1 0 0 ...
## $ attach : num [1:3921] 0 0 0 0 0 0 0 1 0 0 ...
## $ dollar : num [1:3921] 0 0 4 0 0 0 0 0 0 0 ...
## $ winner : Factor w/ 2 levels "no","yes": 1 1 1 1 1 1 1 1 1 1 ...
## $ inherit : num [1:3921] 0 0 1 0 0 0 0 0 0 0 ...
## $ viagra : num [1:3921] 0 0 0 0 0 0 0 0 0 0 ...
## $ password : num [1:3921] 0 0 0 0 2 2 0 0 0 0 ...
## $ num_char : num [1:3921] 11.37 10.5 7.77 13.26 1.23 ...
## $ line_breaks : int [1:3921] 202 202 192 255 29 25 193 237 69 68 ...
## $ format : Factor w/ 2 levels "0","1": 2 2 2 2 1 1 2 2 1 2 ...
## $ re_subj : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
## $ exclaim_subj: num [1:3921] 0 0 0 0 0 0 0 0 0 0 ...
## $ urgent_subj : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
## $ exclaim_mess: num [1:3921] 0 1 6 48 1 1 1 18 1 0 ...
## $ number : Factor w/ 3 levels "none","small",..: 3 2 2 2 1 1 3 2 2 2 ...
Data set email terdiri dari 3921 observasi dengan 21 macam variabel. Ke dua puluh satu variabel ini terdiri dari 4 macam tipe data yaitu integer, numeric, factor, dan POSIXct.
# ggplot2, dplyr, and openintro are loaded
# Compute summary statistics
email %>%
group_by(spam) %>%
summarize(
median(num_char),
IQR(num_char))
## # A tibble: 2 x 3
## spam `median(num_char)` `IQR(num_char)`
## <fct> <dbl> <dbl>
## 1 0 6.83 13.6
## 2 1 1.05 2.82
Median dari data num_char yang tidak spam adalah 6.83 sedangkan yang bersfiat spam adalah 1.05. Sedangkan IQR dari num_char yang tidak spam adalah 13.58 dan yang bersifat spam adalah 2.82.
table(email$spam)
##
## 0 1
## 3554 367
Jumlah not_spam jauh lebih banyak dari email yang bersifat spam. Perbandingannya hampir mencapai 10 : 1.
email <- email %>%
mutate(spam = factor(ifelse(spam == 0, "not-spam", "spam")))
# Create plot
email %>%
mutate(log_num_char = log(num_char)) %>%
ggplot(aes(x = spam, y = log_num_char)) +
geom_boxplot()
Visualisasi diatas menunuukan bahwa terdapat beberapa pencilan baik pada email bersifat spam dengan email yang tidak bersifat spam.
Outlier pada not_spam berjumlah lebih banyak ketimbang yang bersifat spam.
Not spam: Yang dikatakan sebagai pencilan ialah ketika nilainya dibawah sekita -2,5 dan diatas 5.1.
Spam : Yang dikatakan seagai pencilan ialah ketika nilainya sekitar diatas 2.75 dan dibawah 2.6.
###– Spam and num_char interpretation The median length of not-spam emails is greater than that of spam emails
###– Spam and !!!
# Compute center and spread for exclaim_mess by spam
email %>%
group_by(spam) %>%
summarize(
median(exclaim_mess),
IQR(exclaim_mess))
## # A tibble: 2 x 3
## spam `median(exclaim_mess)` `IQR(exclaim_mess)`
## <fct> <dbl> <dbl>
## 1 not-spam 1 5
## 2 spam 0 1
## # A tibble: 2 x 3
## spam `median(exclaim_mess)` `IQR(exclaim_mess)`
## <fctr> <dbl> <dbl>
## 1 not-spam 1 5
## 2 spam 0 1
Dari tabel diatas dapat dilihat bahwa median dari excalim_mess dari pesan bersifat tidak spam adalah 1 dengankan untuk pesan bersfiat spam adalah 0. Sedangkan IQR exclaim_mess dari pesan spam adalah 1 dan pesan tidak bersifat spam bernilai 5.
table(email$exclaim_mess)
##
## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
## 1435 733 507 128 190 113 115 51 93 45 85 17 56 20 43 11
## 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
## 29 12 26 5 29 9 15 3 11 6 11 1 6 8 13 12
## 32 33 34 35 36 38 39 40 41 42 43 44 45 46 47 48
## 13 3 3 2 3 3 1 2 1 1 3 3 5 3 2 1
## 49 52 54 55 57 58 62 71 75 78 89 94 96 139 148 157
## 3 1 1 4 2 2 2 1 1 1 1 1 1 1 1 1
## 187 454 915 939 947 1197 1203 1209 1236
## 1 1 1 1 1 1 2 1 1
Tabel diatas merupakan tabel frekuensi dari exclaim_mess. Exclaim_mess paling sering muncul(modus) ialah 0 sebanyak 1435. Selain itu terdapat sebuah exclaim_mess berisi 1236.
# Create plot for spam and exclaim_mess
email %>%
mutate(log_exclaim_mess = log(exclaim_mess)) %>%
ggplot(aes(x = log_exclaim_mess)) +
geom_histogram() +
facet_wrap(~ spam)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 1435 rows containing non-finite values (stat_bin).
Dari visualisasi diatas dapat dilihat bahwa sebagian besar email spam maupun tidak spam kita tidak memiliki tanda seru.
###– Spam and !!! interpretation The most common value of exclaim_mess in both classes of email is zero (a log(exclaim_mess) of -4.6 after adding .01). Even after a transformation, the distribution of exclaim_mess in both classes of email is right-skewed. The typical number of exclamations in the not-spam group appears to be slightly higher than in the spam group. ####Check-in 1 Zero inflation in the exclaim_mess variable you can analyze the two part separatly or turn it into a categorical variable of is-zero, not-zero Could make a barchart need to decide if you are more interested in counts or proportions ###– Collapsing levels
table(email$image)
##
## 0 1 2 3 4 5 9 20
## 3811 76 17 11 2 2 1 1
Tabel diatas menunjukan bahwa mayoritas pesan email yang didaptkan tidak mengandung gambar. Akan tetapi terdapat sebuah email yang mengandiung 20 gambar.
# Create plot of proportion of spam by image
email %>%
mutate(has_image = image > 0) %>%
ggplot(aes(x = has_image, fill = spam)) +
geom_bar(position = "fill")
Dari visualisasi diatas dapat kita lihat bahwa pesan dengan gambar cenderung bersifat tidak spam.
###– Image and spam interpretation An email without an image is more likely to be not-spam than spam
###– Data Integrity
# Test if images count as attachments
sum(email$image > email$attach)
## [1] 0
Jumlah email yang berisi gambar lebih banyak dari arrachment bernilai 0 observasi.
There are no emails with more images than attachments so these most be counted as attachments also
###– Answering questions with chains
## Within non-spam emails, is the typical length of emails shorter for
## those that were sent to multiple people?
email %>%
filter(spam == "not-spam") %>%
group_by(to_multiple) %>%
summarize(median(num_char))
## # A tibble: 2 x 2
## to_multiple `median(num_char)`
## <fct> <dbl>
## 1 0 7.20
## 2 1 5.36
Dari data diatas kita dapat menjawab ya. Email yang dikirmkan kepada beberapa orang memiliki jumlah kata yang lebih sedikit dimbandingkan yang tidak ke beberapa orang.
Yes
# Question 1
## For emails containing the word "dollar", does the typical spam email
## contain a greater number of occurences of the word than the typical non-spam email?
table(email$dollar)
##
## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
## 3175 120 151 10 146 20 44 12 35 10 22 10 20 7 14 5
## 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32
## 23 2 14 1 10 7 12 7 7 3 7 1 5 1 1 2
## 34 36 40 44 46 48 54 63 64
## 1 2 3 3 2 1 1 1 3
email %>%
filter(dollar > 0) %>%
group_by(spam) %>%
summarize(median(dollar))
## # A tibble: 2 x 2
## spam `median(dollar)`
## <fct> <dbl>
## 1 not-spam 4
## 2 spam 2
Tidak, email yang mengandung lebih banyak dollar cenderung dikategorikan sebagai email bukan spam,
# Question 2
## If you encounter an email with greater than 10 occurrences of the word "dollar",
## is it more likely to be spam or not -spam?
email %>%
filter(dollar > 10) %>%
ggplot(aes(x = spam)) +
geom_bar()
Kemungkinan besar pesan email yang didapat bersifat bukan spam.
Not-spam, at least in this dataset
####Check-in 2 ###– What’s in a number?
levels(email$number)
## [1] "none" "small" "big"
# Reorder levels
email$number <- factor(email$number, levels = c("none","small","big"))
# Construct plot of number
ggplot(email, aes(x = number)) +
geom_bar() +
facet_wrap( ~ spam)
###– What’s in a number interpretation Given that an email contains a
small number, it is more likely to be not-spam. Given that an email
contains a big number, it is more likely to be not-spam. Within both
spam and not-spam, the most common number is a small one.
Visualisasi diatas menujunkan bahwa
1. Email yang berisi angka kecil cenderung bersifat tidak spam.
2. Email yang berisi angla bersar juga cenderyng tidak dapat dikatakan sebagai pesan spam.