Ini adalah catatan untuk memandu secara singkat dalam melakukan manipulasi/transformasi data menggunakan R dan beberapa package yang menjadi bagian dari package tidyverse. Tujuan dari tutorial ini adalah agar peserta dapat mencoba mengakses data yang berasal dari database (pada kesempatan ini menggunakan MySQL) dan dari file CSV yang dapat diunduh. Database yang akan diakses telah disediakan oleh pembicara di localhost-nya. Anda hanya dapat mengaksesnya ketika kegiatan sedang berlangsung.

1. Prasyarat

Untuk dapat mengikuti tutorial ini dengan baik, ada beberapa hal yang perlu dipersiapkan oleh peserta. Yaitu:

  1. Koneksi internet yang baik

  2. Menginstall software

    1. R program https://cran.r-project.org/

    2. RStudio https://www.rstudio.com/products/rstudio/download/

  3. Data & Script yang dapat diperoleh dari repository ini dan pada database yang disediakan pembicara.

  4. Package R yang dibutuhkan: readr, tidyr, dplyr (atau tidyverse) dan RMySQL

Jika Anda ingin mencoba diluar kegiatan, Anda dapat menginstall package nycflights13 untuk memperoleh data yang digunakan pada database.

install.packages("nycflights13")
library(nycflights13)

2. Install Packages

Jalankan perintah di bawah ini untuk install package (jika Anda belum pernah install) yang akan digunakan untuk dapat mengikuti tutorial ini sampai selesai.

install.packages(c("readr", "tidyr", "dplyr", "RMySQL"))

Panggil package yang sudah Anda install dengan fungsi library().

# Panggil package yang sudah terisntall
library(RMySQL)
## Loading required package: DBI
library(readr)
library(tidyr)
library(dplyr)
## 
## 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

Package reader, tidyr dan dplyr (dan beberapa package lain yang tidak digunakan di tutorial ini, misalnya ggplot2 untuk visualisasi) termasuk dalam bagian package tidyverse. tidyverse adalah kumpulan package yang dibuat oleh Hadley Wickham dkk untuk kebutuhan data science menggunakan R.

RMySQL digunakan untuk membuat koneksi antara R dan database MySQL. Beberapa fungsi yang akan digunakan pada tutorial ini antara lain dbConnect() yang berasal dari package DBI untuk membuat koneksi, dbReadTable() untuk import data dari database ke R dan fungsi dbDisconnect() untuk memutuskan koneksi yang sudah tidak digunakan. readr berguna untuk import data dari tabular data file (csv, text file, dll). tidyr memiliki fungi-fungsi untuk “merapihkan” data. Terutama yang sering digunakan adalah fungsi gather() dan spread(). dplyr adalah package yang sangat berguna untuk melakukan manipulasi/transformasi data menggunakan R.

Tidyverse

Tidyverse

3. Koneksi ke Database dan Import Data

Data diperoleh dari packages nycflights13 yang disimpan ke dalam database dan berupa file CSV untuk disesuaikan dengan kebutuhan tutorial. Data ini terdiri dari 336,776 penerbangan dari New York City (NYC) selama tahun 2013. Data asli berasal dari US Bureau of Transportation Statistics, dan dapat dilihat dokumentasinya dengan ?nycflights13::flights.

Untuk data yang tersedia di database Anda dapat membuat koneksi ke database dengan perintah berikut ini.

srv <- "localhost" # ganti dengan IP yang akan diberikan oleh pembicara
port <- 3306
dbn <- "nycflights"
usr <- "user1"
pwd <- "P@ssw0rd"

mycon <- dbConnect(MySQL(), 
                   host = srv, 
                   dbname = dbn, 
                   user = usr, 
                   password = pwd, 
                   port = port)
dbListTables(mycon)
## [1] "airlines" "airports" "flights"  "planes"   "weather"
flights <- as_tibble(dbReadTable(mycon, "flights"))
airlines <- as_tibble(dbReadTable(mycon, "airlines"))
airports <- as_tibble(dbReadTable(mycon, "airports"))
weather <- as_tibble(dbReadTable(mycon, "weather"))
planes <- as_tibble(dbReadTable(mycon, "planes"))

Penting untuk menutup koneksi ke database setelah selesai mengakses dan tidak menggunakan koneksi tersebut. Memutuskan koneksi dapat menggunakan fungsi dbDisconnect(mycon).

Untuk data CSV yang akan digunakan dapat Anda unduh terlebih dahulu dan simpan di sebuah folder working directory, misalnya di dalam folder D:/pelatihanR dengan nama prices.csv. Untuk mengaktifkan working directory pada folder tersebut Anda dapat gunakan fungsi setwd("D:/pelatihanR").

download.file(url = "https://raw.githubusercontent.com/aephidayatuloh/manipulasi-data/master/prices.csv", 
              destfile = "D:/pelatihanR/prices.csv")
download.file(url = "https://raw.githubusercontent.com/aephidayatuloh/manipulasi-data/master/specialdays.csv", 
              destfile = "D:/pelatihanR/specialdays.csv")

# Import data dari CSV tersebut ke R
prices <- read_delim("D:/pelatihanR/prices.csv", delim = ";")
specialdays <- read_csv("D:/pelatihanR/specialdays.csv")

Atau dengan cara langsung import tanpa unduh terlebih dahulu.

prices <- read_delim("https://raw.githubusercontent.com/aephidayatuloh/manipulasi-data/master/prices.csv", delim = ";")
## Parsed with column specification:
## cols(
##   year = col_double(),
##   month = col_character(),
##   day = col_character(),
##   origin = col_character(),
##   dest = col_character(),
##   sched_dep_time = col_character(),
##   tailnum = col_character(),
##   ticket = col_character(),
##   cost = col_character()
## )
specialdays <- read_csv("https://raw.githubusercontent.com/aephidayatuloh/manipulasi-data/master/specialdays.csv")
## Parsed with column specification:
## cols(
##   year = col_double(),
##   month = col_double(),
##   day = col_double(),
##   holiday = col_character()
## )

File prices.csv dibaca menggunakan fungsi read_delim() karena pemisah antar variablenya adalah titik-koma (:), maka dari itu disebutkan juga delim = ";". Untuk file specialdays.csv dibaca menggunakan fungsi read_csv() karena menggunakan tanda koma (,) sebagai pemisah antar variable.

Keterangan variable:

flights

Variable Keterangan
year,month,day Date of departure
dep_time, arr_time Actual departure and arrival times (format HHMM or HMM), local tz.
sched_dep_time, sched_arr_time Scheduled departure and arrival times (format HHMM or HMM), local tz.
dep_delay, arr_delay Departure and arrival delays, in minutes. Negative times represent early departures/arrivals.
hour, minute Time of scheduled departure broken into hour and minutes.
carrier Two letter carrier abbreviation. See ?airlines to get name.
tailnum Plane tail number
flight Flight number
origin, dest Origin and destination. See ?airports for additional metadata.
air_time Amount of time spent in the air, in minutes.
distance Distance between airports, in miles.
time_hour Scheduled date and hour of the flight as a POSIXct date. Along with origin, can be used to join flights data to weather data.

airlines

Variable Keterangan
carrier Two letter abbreviation
name Full name

planes

Variable Keterangan
tailnum Tail number
year Year manufactured
type Type of plane
manufacturer,model Manufacturer and model
engines,seats Number of engines and seats
speed Average cruising speed in mph
engine Type of engine

weather

Variable Keterangan
origin Weather station. Named origin to faciliate merging with flights data.
year,month,day,hour Time of recording.
temp,dewp Temperature and dewpoint in Fahrenheit.
humid Relative humidity.
wind_dir,wind_speed,wind_gust Wind direction (in degrees), speed and gust speed (in mph).
precip Precipitation, in inches.
pressure Sea level pressure in millibars.
visib Visibility in miles
time_hour Date and hour of the recording as a POSIXct date.

airports

Variable Keterangan
faa FAA airport code.
name Usual name of the aiport.
lat,lon Location of airport.
alt Altitude, in feet.
tz Timezone offset from GMT.
dst Daylight savings time zone. A = Standard US DST: starts on the second Sunday of March, ends on the first Sunday of November. U = unknown. N = no dst.
tzone IANA time zone, as determined by GeoNames webservice

prices

Variable Keterangan
year,month,day Date of departure
origin,dest Origin and destination. See ?airports for additional metadata.
sched_dep_time Scheduled departure and arrival times (format HHMM or HMM), local tz.
tailnum Plane tail number
ticket Average ticket price per person for a flight
cost Average operating costs per person for a flight

specialdays

Variable Keterangan
year,month,day Date of departure
holiday Name of special day in United States

3. Cakupan Materi

Materi yang akan dibahas:

Fungsi/Operator Materi
distinct() Mendapatkan nilai unik/tidak duplikat dari data frame atau variable
select() Subset variable berdasarkan nama/indeks variable
slice() atau filter() Subset baris berdasarkan indeks baris atau nilai dari satu atau beberapa variabel
arrange() Mengurutkan sebuah data frame berdasarkan satu atau beberapa variable
na_if(),drop_na(),replace_na() Penanganan NA (missing value)
%>% Operator Pipes untuk beberapa fungsi secara berurutan/sequence
mutate() Membuat variabel baru/menghitung dari variabel yang sudah ada
count() dan spread() Tabel frekuensi dan transformasi tabel
summarise() dan group_by() Ringkasan (summary) variabel atau berdasarkan group
inner_join() dan left_join() Merge/Join tabel

4. Materi

Setelah berhasil import data dari MySQL dan CSV, selanjutnya kita akan mengeksplorasi data tersebut.

dim(flights)
## [1] 336776     19
glimpse(flights)
## Observations: 336,776
## Variables: 19
## $ year           <dbl> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013,...
## $ month          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ day            <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ dep_time       <dbl> 517, 533, 542, 544, 554, 554, 555, 557, 557, 55...
## $ sched_dep_time <dbl> 515, 529, 540, 545, 600, 558, 600, 600, 600, 60...
## $ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2...
## $ arr_time       <dbl> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 7...
## $ sched_arr_time <dbl> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 7...
## $ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -...
## $ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV",...
## $ flight         <dbl> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79...
## $ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN...
## $ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR"...
## $ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL"...
## $ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138...
## $ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 94...
## $ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,...
## $ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ time_hour      <chr> "2013-01-01 05:00:00", "2013-01-01 05:00:00", "...
head(flights)
## # A tibble: 6 x 19
##    year month   day dep_time sched_dep_time dep_delay arr_time
##   <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
## 1  2013     1     1      517            515         2      830
## 2  2013     1     1      533            529         4      850
## 3  2013     1     1      542            540         2      923
## 4  2013     1     1      544            545        -1     1004
## 5  2013     1     1      554            600        -6      812
## 6  2013     1     1      554            558        -4      740
## # ... with 12 more variables: sched_arr_time <dbl>, arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>
summary(flights)
##       year          month             day           dep_time   
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400  
##                                                  NA's   :8255  
##  sched_dep_time   dep_delay          arr_time    sched_arr_time
##  Min.   : 106   Min.   : -43.00   Min.   :   1   Min.   :   1  
##  1st Qu.: 906   1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124  
##  Median :1359   Median :  -2.00   Median :1535   Median :1556  
##  Mean   :1344   Mean   :  12.64   Mean   :1502   Mean   :1536  
##  3rd Qu.:1729   3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945  
##  Max.   :2359   Max.   :1301.00   Max.   :2400   Max.   :2359  
##                 NA's   :8255      NA's   :8713                 
##    arr_delay          carrier              flight       tailnum         
##  Min.   : -86.000   Length:336776      Min.   :   1   Length:336776     
##  1st Qu.: -17.000   Class :character   1st Qu.: 553   Class :character  
##  Median :  -5.000   Mode  :character   Median :1496   Mode  :character  
##  Mean   :   6.895                      Mean   :1972                     
##  3rd Qu.:  14.000                      3rd Qu.:3465                     
##  Max.   :1272.000                      Max.   :8500                     
##  NA's   :9430                                                           
##     origin              dest              air_time        distance   
##  Length:336776      Length:336776      Min.   : 20.0   Min.   :  17  
##  Class :character   Class :character   1st Qu.: 82.0   1st Qu.: 502  
##  Mode  :character   Mode  :character   Median :129.0   Median : 872  
##                                        Mean   :150.7   Mean   :1040  
##                                        3rd Qu.:192.0   3rd Qu.:1389  
##                                        Max.   :695.0   Max.   :4983  
##                                        NA's   :9430                  
##       hour           minute       time_hour        
##  Min.   : 1.00   Min.   : 0.00   Length:336776     
##  1st Qu.: 9.00   1st Qu.: 8.00   Class :character  
##  Median :13.00   Median :29.00   Mode  :character  
##  Mean   :13.18   Mean   :26.23                     
##  3rd Qu.:17.00   3rd Qu.:44.00                     
##  Max.   :23.00   Max.   :59.00                     
## 

dim() menampilkan banyaknya baris dan variable dari suatu data frame.

glimpse() serupa dengan str() dari base-R, bertujuan untuk melihat tipe dan struktur objek. Jika objek tersebut adalah data frame, maka akan menghasilkan banyaknya baris (observations) dan variable (variables). Fungsi ini juga menampilkan nama variabel, tipe variabel, dan beberapa baris pertama dari data.

head() berguna untuk melihat atau menampilkan beberapa baris pertama dari data frame. Secara default head() menggunakan n = 6 untuk menentukan banyaknya baris yang akan ditampilkan. Jika Anda ingin melihat 10 baris pertama, maka cukup mennggantinya menjadi head(flights, n = 10). Namun jika yang ingin Anda tampilkan ada beberapa baris terakhir dari data frame, gunakan tail().

summary() menghasilkan beberapa nilai statistik deskriptif untuk masing-masing variabel jika yang dimasukan sebagai argumen adalah data frame. Untuk variabel numerik maka akan menhasilkan nilai minimum (Min.), quantil pertama (1st Qu.), median (Median), rata-rata (Mean), quantil ketiga (3rd Qu.), maksimum (Max.) dan banyaknya missing value (NA's) jika ada. Untuk variabel kategorik (character atau factor) makan akan menghasilkan banyaknya data (Length), kelas (Class) dan mode (Mode).

4.1. Mengambil nilai unik (tidak duplikasi) dari sebuah variable

Hal ini sama seperti melakukan remove duplicate di Ms Excel untuk satu variabel.

distinct(flights, year)
## # A tibble: 1 x 1
##    year
##   <dbl>
## 1  2013
distinct(flights, origin)
## # A tibble: 3 x 1
##   origin
##   <chr> 
## 1 EWR   
## 2 LGA   
## 3 JFK
distinct(flights, dest)
## # A tibble: 105 x 1
##    dest 
##    <chr>
##  1 IAH  
##  2 MIA  
##  3 BQN  
##  4 ATL  
##  5 ORD  
##  6 FLL  
##  7 IAD  
##  8 MCO  
##  9 PBI  
## 10 TPA  
## # ... with 95 more rows

Untuk mendapatkan nilai unik dari semua baris berdasarkan variabel tertentu tambahkan opsi .keep_all = TRUE setelah nama variable dalam fungsi distinct().

distinct(flights, dest, .keep_all = TRUE)
## # A tibble: 105 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      542            540         2      923
##  3  2013     1     1      544            545        -1     1004
##  4  2013     1     1      554            600        -6      812
##  5  2013     1     1      554            558        -4      740
##  6  2013     1     1      555            600        -5      913
##  7  2013     1     1      557            600        -3      709
##  8  2013     1     1      557            600        -3      838
##  9  2013     1     1      558            600        -2      849
## 10  2013     1     1      558            600        -2      853
## # ... with 95 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>
distinct(flights)
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      533            529         4      850
##  3  2013     1     1      542            540         2      923
##  4  2013     1     1      544            545        -1     1004
##  5  2013     1     1      554            600        -6      812
##  6  2013     1     1      554            558        -4      740
##  7  2013     1     1      555            600        -5      913
##  8  2013     1     1      557            600        -3      709
##  9  2013     1     1      557            600        -3      838
## 10  2013     1     1      558            600        -2      753
## # ... with 336,766 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>

4.2. Memilih atau membuang beberapa variable yang akan/tidak digunakan

Untuk membuat data frame dari hasil select() Anda dapat menuliskan namadataframe <- select(...). Argumen pertama dari select() adalah data frame yang ingin kita subset variabel tertentu saja. Selanjutnya tuliskan nama variable yang Anda inginkan ada di data frame yang baru. Anda dapat menuliskan nama masing-masing variable atau dapat juga dengan menuliskan urutan (indeks) variabel.

select(flights, month, day, dep_time, dep_delay, arr_time, arr_delay, origin, dest)
## # A tibble: 336,776 x 8
##    month   day dep_time dep_delay arr_time arr_delay origin dest 
##    <dbl> <dbl>    <dbl>     <dbl>    <dbl>     <dbl> <chr>  <chr>
##  1     1     1      517         2      830        11 EWR    IAH  
##  2     1     1      533         4      850        20 LGA    IAH  
##  3     1     1      542         2      923        33 JFK    MIA  
##  4     1     1      544        -1     1004       -18 JFK    BQN  
##  5     1     1      554        -6      812       -25 LGA    ATL  
##  6     1     1      554        -4      740        12 EWR    ORD  
##  7     1     1      555        -5      913        19 EWR    FLL  
##  8     1     1      557        -3      709       -14 LGA    IAD  
##  9     1     1      557        -3      838        -8 JFK    MCO  
## 10     1     1      558        -2      753         8 LGA    ORD  
## # ... with 336,766 more rows
select(flights, c(2:4, 6:7, 9, 13:14))
## # A tibble: 336,776 x 8
##    month   day dep_time dep_delay arr_time arr_delay origin dest 
##    <dbl> <dbl>    <dbl>     <dbl>    <dbl>     <dbl> <chr>  <chr>
##  1     1     1      517         2      830        11 EWR    IAH  
##  2     1     1      533         4      850        20 LGA    IAH  
##  3     1     1      542         2      923        33 JFK    MIA  
##  4     1     1      544        -1     1004       -18 JFK    BQN  
##  5     1     1      554        -6      812       -25 LGA    ATL  
##  6     1     1      554        -4      740        12 EWR    ORD  
##  7     1     1      555        -5      913        19 EWR    FLL  
##  8     1     1      557        -3      709       -14 LGA    IAD  
##  9     1     1      557        -3      838        -8 JFK    MCO  
## 10     1     1      558        -2      753         8 LGA    ORD  
## # ... with 336,766 more rows

Jika variabel yang ingin Anda pilih cukup banyak sedangkan variabel yang ingin Anda buang lebih sedikit, Anda dapat menuliskan nama variabel dengan menambahkan tanda negatif (-) di depan nama atau indeks masing-masing variabel.

select(flights, -year)
## # A tibble: 336,776 x 18
##    month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>          <dbl>
##  1     1     1      517            515         2      830            819
##  2     1     1      533            529         4      850            830
##  3     1     1      542            540         2      923            850
##  4     1     1      544            545        -1     1004           1022
##  5     1     1      554            600        -6      812            837
##  6     1     1      554            558        -4      740            728
##  7     1     1      555            600        -5      913            854
##  8     1     1      557            600        -3      709            723
##  9     1     1      557            600        -3      838            846
## 10     1     1      558            600        -2      753            745
## # ... with 336,766 more rows, and 11 more variables: arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>
select(flights, -1)
## # A tibble: 336,776 x 18
##    month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>          <dbl>
##  1     1     1      517            515         2      830            819
##  2     1     1      533            529         4      850            830
##  3     1     1      542            540         2      923            850
##  4     1     1      544            545        -1     1004           1022
##  5     1     1      554            600        -6      812            837
##  6     1     1      554            558        -4      740            728
##  7     1     1      555            600        -5      913            854
##  8     1     1      557            600        -3      709            723
##  9     1     1      557            600        -3      838            846
## 10     1     1      558            600        -2      753            745
## # ... with 336,766 more rows, and 11 more variables: arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>

4.3. Memilih baris data berdasarkan indeks baris atau nilai pada variabel tertentu

Ketika Anda ingin memilih sebagian baris saja dari data frame, Anda dapat menggunakan fungsi slice() atau filter().

slice() berfungsi untuk mensubset baris data berdasarkan indeks barisnya. Misalkan, slice(flights, 1:100) berarti Anda memilih data pada posisi baris ke-1 s/d ke-100. Posisi baris 1:100 adalah vector numerik integer yang ingin dipilih.

# memilih baris ke-1 s/d 1000
slice(flights, 1:1000)
## # A tibble: 1,000 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      533            529         4      850
##  3  2013     1     1      542            540         2      923
##  4  2013     1     1      544            545        -1     1004
##  5  2013     1     1      554            600        -6      812
##  6  2013     1     1      554            558        -4      740
##  7  2013     1     1      555            600        -5      913
##  8  2013     1     1      557            600        -3      709
##  9  2013     1     1      557            600        -3      838
## 10  2013     1     1      558            600        -2      753
## # ... with 990 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>

filter() berfungsi untuk memilih sebagian data berdasarkan nilai dari satu atau lebih variabel.

filter(flights, dep_delay >= 10)
## # A tibble: 85,693 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      611            600        11      945
##  2  2013     1     1      623            610        13      920
##  3  2013     1     1      632            608        24      740
##  4  2013     1     1      732            645        47     1011
##  5  2013     1     1      743            730        13     1107
##  6  2013     1     1      743            730        13     1059
##  7  2013     1     1      749            710        39      939
##  8  2013     1     1      811            630       101     1047
##  9  2013     1     1      826            715        71     1136
## 10  2013     1     1      848           1835       853     1001
## # ... with 85,683 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>
filter(flights, dep_delay >= 10 & origin == "JFK")
## # A tibble: 27,629 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      611            600        11      945
##  2  2013     1     1      743            730        13     1107
##  3  2013     1     1      743            730        13     1059
##  4  2013     1     1      826            715        71     1136
##  5  2013     1     1      848           1835       853     1001
##  6  2013     1     1      909            810        59     1331
##  7  2013     1     1      912            900        12     1241
##  8  2013     1     1      920            905        15     1039
##  9  2013     1     1      921            900        21     1237
## 10  2013     1     1      933            904        29     1252
## # ... with 27,619 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>
filter(flights, month == 1 & day == 1 & origin == "JFK" & dest == "ATL")
## # A tibble: 5 x 19
##    year month   day dep_time sched_dep_time dep_delay arr_time
##   <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
## 1  2013     1     1      606            610        -4      837
## 2  2013     1     1      807            810        -3     1043
## 3  2013     1     1     1325           1330        -5     1606
## 4  2013     1     1     1621           1548        33     1904
## 5  2013     1     1     1856           1855         1     2142
## # ... with 12 more variables: sched_arr_time <dbl>, arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>
filter(flights, is.na(dep_time))
## # A tibble: 8,255 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1       NA           1630        NA       NA
##  2  2013     1     1       NA           1935        NA       NA
##  3  2013     1     1       NA           1500        NA       NA
##  4  2013     1     1       NA            600        NA       NA
##  5  2013     1     2       NA           1540        NA       NA
##  6  2013     1     2       NA           1620        NA       NA
##  7  2013     1     2       NA           1355        NA       NA
##  8  2013     1     2       NA           1420        NA       NA
##  9  2013     1     2       NA           1321        NA       NA
## 10  2013     1     2       NA           1545        NA       NA
## # ... with 8,245 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>

4.4. Mengurutkan data

Mengurutkan data frame menggunakan fungsi arrange() sangat mudah.

# Urutkan data frame flights berdasarkan variabel `origin`
arrange(flights, origin)
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      554            558        -4      740
##  3  2013     1     1      555            600        -5      913
##  4  2013     1     1      558            600        -2      923
##  5  2013     1     1      559            600        -1      854
##  6  2013     1     1      601            600         1      844
##  7  2013     1     1      606            610        -4      858
##  8  2013     1     1      607            607         0      858
##  9  2013     1     1      608            600         8      807
## 10  2013     1     1      615            615         0      833
## # ... with 336,766 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>
# Urutkan data frame flights berdasarkan variabel `origin` dan `dest`
arrange(flights, origin, dest)
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1     1315           1317        -2     1413
##  2  2013     1     1     1655           1621        34     1804
##  3  2013     1     1     2056           2004        52     2156
##  4  2013     1     2     1332           1327         5     1419
##  5  2013     1     2     1746           1621        85     1835
##  6  2013     1     2     2148           2004       104     2234
##  7  2013     1     3     1716           1619        57     1803
##  8  2013     1     3     2031           2038        -7     2131
##  9  2013     1     4     1618           1619        -1     1714
## 10  2013     1     4     2031           2000        31     2131
## # ... with 336,766 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>
# Urutkan data frame flights berdasarkan variabel `origin` secara ascending dan `dest` secara descending
arrange(flights, origin, desc(dest))
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     2      905            822        43     1313
##  2  2013     1     3      848            850        -2     1149
##  3  2013     1     4      901            850        11     1120
##  4  2013     1     6      843            848        -5     1053
##  5  2013     1     7      858            850         8     1105
##  6  2013     1     8      847            850        -3     1116
##  7  2013     1     9      845            850        -5     1131
##  8  2013     1    10      847            850        -3     1120
##  9  2013     1    11      847            850        -3     1123
## 10  2013     1    13      849            848         1     1121
## # ... with 336,766 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>

4.5. Penanganan missing values

Untuk kebutuhan ilustrasi pada bagian ini dengan fungsi na_if(), Anda akan mengganti nilai NA (missing value) menjadi sebuah nilai tertentu, misalnya jika air_time missing akan diganti menjadi nilai -999.

# Banyaknya NA
sum(is.na(flights["air_time"]))
## [1] 9430
flights_na999 <- flights
# Merubah NA dengan -999
flights_na999$air_time <- if_else(is.na(flights$air_time), -999, flights$air_time)

# Banyaknya NA
sum(is.na(flights_na999["air_time"]))
## [1] 0
# Banyaknya NA yang sudah diganti -999
sum(flights_na999["air_time"] == -999)
## [1] 9430
# Ganti nilai NA menjadi -999
flights_na999$air_time <- na_if(flights_na999$air_time, -999)

# Banyaknya -999
filter(flights_na999, air_time == -999)
## # A tibble: 0 x 19
## # ... with 19 variables: year <dbl>, month <dbl>, day <dbl>,
## #   dep_time <dbl>, sched_dep_time <dbl>, dep_delay <dbl>, arr_time <dbl>,
## #   sched_arr_time <dbl>, arr_delay <dbl>, carrier <chr>, flight <dbl>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
## #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <chr>
# Banyaknya NA
sum(is.na(flights_na999$air_time))
## [1] 9430
# Membuang semua baris yang mengandung NA
flights_NoNA <- drop_na(flights)

# Mengganti NA pada masing-masing variabel dengan nilai tertentu
replace_na(flights, list(dep_time = 0, dep_delay = 0, arr_time = mean(flights$arr_time, na.rm = TRUE), arr_delay = median(flights$arr_delay, na.rm = TRUE)))
## # A tibble: 336,776 x 19
##     year month   day dep_time sched_dep_time dep_delay arr_time
##    <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
##  1  2013     1     1      517            515         2      830
##  2  2013     1     1      533            529         4      850
##  3  2013     1     1      542            540         2      923
##  4  2013     1     1      544            545        -1     1004
##  5  2013     1     1      554            600        -6      812
##  6  2013     1     1      554            558        -4      740
##  7  2013     1     1      555            600        -5      913
##  8  2013     1     1      557            600        -3      709
##  9  2013     1     1      557            600        -3      838
## 10  2013     1     1      558            600        -2      753
## # ... with 336,766 more rows, and 12 more variables: sched_arr_time <dbl>,
## #   arr_delay <dbl>, carrier <chr>, flight <dbl>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <chr>

Fungsi replace_na() menggunakan argumen sebuah list untuk menentukan nilai pengganti NA pada sebuah variabel. Dari contoh di atas, NA pada dep_time dan dep_delay diganti menjadi 0 (nol), NA di arr_time diganti dengan rata-rata arr_time, sedangkan NA di arr_delay diganti dengan nilai median dari arr_delay.

4.6. Operator Pipes %>%

Seringkali proses data preparation membutuhkan banyak proses atau tahapan. Sekarang jika kita ingin melakukan beberapa proses sekaligus, salah satunya kita akan membuat script kurang lebih seperti ini.

selected <- select(flights, dep_delay, arr_time, arr_delay, origin, dest, air_time)
filtered <- filter(selected, dep_delay >= 10 & origin == "JFK")
hasil <- arrange(filtered, origin)
hasil
## # A tibble: 27,629 x 6
##    dep_delay arr_time arr_delay origin dest  air_time
##        <dbl>    <dbl>     <dbl> <chr>  <chr>    <dbl>
##  1        11      945        14 JFK    SFO        366
##  2        13     1107         7 JFK    LAX        358
##  3        13     1059         3 JFK    SEA        349
##  4        71     1136        51 JFK    MIA        160
##  5       853     1001       851 JFK    BWI         41
##  6        59     1331        16 JFK    STT        184
##  7        12     1241        21 JFK    MIA        166
##  8        15     1039        14 JFK    IAD         52
##  9        21     1237        10 JFK    LAX        333
## 10        29     1252        42 JFK    FLL        170
## # ... with 27,619 more rows

Atau ada juga yang menuliskan seperti berikut ini.

hasil <- arrange(filter(select(flights, dep_delay, arr_time, arr_delay, origin, dest, air_time), dep_delay >= 10 & origin == "JFK"), origin)
hasil
## # A tibble: 27,629 x 6
##    dep_delay arr_time arr_delay origin dest  air_time
##        <dbl>    <dbl>     <dbl> <chr>  <chr>    <dbl>
##  1        11      945        14 JFK    SFO        366
##  2        13     1107         7 JFK    LAX        358
##  3        13     1059         3 JFK    SEA        349
##  4        71     1136        51 JFK    MIA        160
##  5       853     1001       851 JFK    BWI         41
##  6        59     1331        16 JFK    STT        184
##  7        12     1241        21 JFK    MIA        166
##  8        15     1039        14 JFK    IAD         52
##  9        21     1237        10 JFK    LAX        333
## 10        29     1252        42 JFK    FLL        170
## # ... with 27,619 more rows

Jika Anda diminta untuk mempelajari script seperti ini saya cukup yakin bahwa Anda akan merasa kesulitan untuk mengetahui proses yang akan dilakukan oleh script tersebut. Script di atas masih sederhana, hanya ada tiga fungsi. Bayangkan jika banyak fungsi yang digunakan secara berurutan, bentuk di atas akan menjadi:

output <- fun_n(...(fun3(fun2(fun1(dataframe, arg1), arg2), arg3), ...), arg_n)

Jika diperhatikan, argumen pertama dari masing-masing fungsi select(), filter(), arrange() dan beberapa fungsi yang lain di dplyr yang sering digunakan untuk transformasi dan eksplorasi data adalah data frame/tibble atau hasil dari proses sebelumnya. Misalnya, hasil dari fungsi select() adalah data frame yang kemudian diproses dengan fungsi filter() untuk memilih baris data tertentu dan hasilnya diteruskan lagi ke fungsi arrange() untuk diurutkan berdasarkan variabel tertentu.

Dengan konsep tidyverse, kita dapat menggunakan operator Pipes %>% agar lebih mudah dalam memahami script karena script tersebut menunjukkan urutan. Perhatikan contoh di bawah ini.

flights %>% 
  select(dep_delay, arr_time, arr_delay, origin, dest, time_hour) %>% 
  filter(origin == "JFK" & between(dep_delay, -10, 100)) %>% 
  arrange(origin, desc(dest)) 
## # A tibble: 104,021 x 6
##    dep_delay arr_time arr_delay origin dest  time_hour          
##        <dbl>    <dbl>     <dbl> <chr>  <chr> <chr>              
##  1        -2      853        -3 JFK    TPA   2013-01-01 06:00:00
##  2         8     1147         2 JFK    TPA   2013-01-01 08:00:00
##  3        -7     1520        -6 JFK    TPA   2013-01-01 12:00:00
##  4        88     1925        80 JFK    TPA   2013-01-01 14:00:00
##  5        24     2052        27 JFK    TPA   2013-01-01 17:00:00
##  6        -9     2211       -33 JFK    TPA   2013-01-01 19:00:00
##  7        -1     2238        -2 JFK    TPA   2013-01-01 19:00:00
##  8        47      140        73 JFK    TPA   2013-01-01 21:00:00
##  9        -5      856         0 JFK    TPA   2013-01-02 06:00:00
## 10        -4     1126        -5 JFK    TPA   2013-01-02 08:00:00
## # ... with 104,011 more rows

Jika dibuat ke dalam kalimat:

“Ambil data penerbangan dari data frame flights kemudian pilih variabel-variable tertentu saja. Selanjutnya filter yang origin-nya dari”JFK" dan waktu keberangkatan antara yang lebih awal 10 menit dan yang delay hingga 100 menit. Kemudian urutkan hasil tersebut berdasarkan origin secara ascending dan berdasarkan dest secara descending."

4.6.1. Penjelasan Operator Pipes %>%

Saya akan coba menjelaskan lebih dalam untuk lebih memahami oprator %>%.

Misalkan f(a, x) adalah sebuah fungsi di R dengan argumen a dan x. kemudian fungsi g(b, z) adalah fungsi lain di R dengan argumen b dan z. Dengan menggunakan operator %>% kita dapat menuliskannya sebagai berikut.

# fungsi f(a, x)
f(a, x) # atau
a %>% f(x)

# fungsi g(b, z)
g(b, z) # atau
b %>% g(z)

Dari kedua contoh di atas, dapat dilihat bahwa a adalah argumen pertama untuk fungsi f() dan b adalah argumen pertama untuk fungsi g(). Operator %>% “menyampaikan” objek a sebagai nilai untuk mengisi argumen pertama pada fungsi f(). Perhatikan ilustrasi di bawah ini.

Ilustrasi Pipes 1

Ilustrasi Pipes 1

Misalkan objek a menjadi argumen pertama fungsi f() dengan a %>% f(x). Kemudia hasil dari a %>% f(x) dijadikan argumen pertama dari fungsi g(). Dengan kata lain b <- a %>% f(x) sehingga b %>% g(z). Hal ini dapat dilakukan secara berurutan dengan operator %>% sebagai berikut.

a %>%
    f(x) %>%
    g(z)

Ilustrasi Pipes 2

Ilustrasi Pipes 2

“Fungsi f() diterapkan terhadap objek a sebagai argumen pertama dan x sebagai argumen kedua dari fungsi f() yang kemudian hasilnya digunakan sebagai argumen pertama pada fungsi g() dengan z sebagai argumen kedua.”

Selanjutnya kita akan gunakan operator %>% dalam tutorial ini.

4.7. Membuat variabel baru

flights %>% 
  select(dep_delay, arr_time, arr_delay, origin, dest, time_hour) %>% 
  filter(origin == "JFK" & between(dep_delay, -10, 100)) %>% 
  arrange(origin, desc(dest)) %>% 
  mutate(is_delay = if_else(dep_delay > 0, 1, 0),
         time_hour = as.POSIXct(time_hour))
## # A tibble: 104,021 x 7
##    dep_delay arr_time arr_delay origin dest  time_hour           is_delay
##        <dbl>    <dbl>     <dbl> <chr>  <chr> <dttm>                 <dbl>
##  1        -2      853        -3 JFK    TPA   2013-01-01 06:00:00        0
##  2         8     1147         2 JFK    TPA   2013-01-01 08:00:00        1
##  3        -7     1520        -6 JFK    TPA   2013-01-01 12:00:00        0
##  4        88     1925        80 JFK    TPA   2013-01-01 14:00:00        1
##  5        24     2052        27 JFK    TPA   2013-01-01 17:00:00        1
##  6        -9     2211       -33 JFK    TPA   2013-01-01 19:00:00        0
##  7        -1     2238        -2 JFK    TPA   2013-01-01 19:00:00        0
##  8        47      140        73 JFK    TPA   2013-01-01 21:00:00        1
##  9        -5      856         0 JFK    TPA   2013-01-02 06:00:00        0
## 10        -4     1126        -5 JFK    TPA   2013-01-02 08:00:00        0
## # ... with 104,011 more rows

Jika dibuat ke dalam kalimat:

“Ambil data penerbangan dari data frame flights kemudian pilih variabel-variable tertentu saja. Selanjutnya filter yang origin-nya dari”JFK" dan waktu keberangkatan antara yang lebih awal 10 menit dan yang delay hingga 100 menit. Kemudian urutkan hasil tersebut berdasarkan origin secara ascending dan berdasarkan dest secara descending. Setelah itu membuat variabel baru bernama is_delay yang menunjukkan apakah suatu penerbangan terjadi delay atau tidak. Kemudian konversi variable time_hour yang masih bertipe character menjadi datetime atau <dttm> dengan nama variabel yang sama, yaitu time_hour."

4.8. Tabel frekuensi dan transformasi tabel

Membuat tabel frekuensi berdasarkan origin dan dest. Gunakan fungsi count() untuk mengetahui banyaknya baris.

flights %>%
  count()
## # A tibble: 1 x 1
##        n
##    <int>
## 1 336776
flights %>% 
  count(origin, dest)
## # A tibble: 224 x 3
##    origin dest      n
##    <chr>  <chr> <int>
##  1 EWR    ALB     439
##  2 EWR    ANC       8
##  3 EWR    ATL    5022
##  4 EWR    AUS     968
##  5 EWR    AVL     265
##  6 EWR    BDL     443
##  7 EWR    BNA    2336
##  8 EWR    BOS    5327
##  9 EWR    BQN     297
## 10 EWR    BTV     931
## # ... with 214 more rows
flights %>% 
  mutate(is_delay = dep_delay > 0) %>% 
  count(origin, is_delay) %>%
  spread(key = origin, value = n)
## # A tibble: 3 x 4
##   is_delay   EWR   JFK   LGA
##   <lgl>    <int> <int> <int>
## 1 FALSE    64885 67385 67819
## 2 TRUE     52711 42031 33690
## 3 NA        3239  1863  3153
  • Membuang NA dengan drop_na() dan menghitung rata-rata delay.
flights %>% 
  drop_na() %>% 
  summarise(rata2_delay = mean(dep_delay))
## # A tibble: 1 x 1
##   rata2_delay
##         <dbl>
## 1        12.6
  • Membuat tabel frekuensi berdasarkan origin dan dest.
flights %>% 
  group_by(origin, dest, month) %>% 
  summarise(rata2_delay = mean(dep_delay, na.rm = TRUE)) %>% 
  arrange(rata2_delay) 
## # A tibble: 2,313 x 4
## # Groups:   origin, dest [224]
##    origin dest  month rata2_delay
##    <chr>  <chr> <dbl>       <dbl>
##  1 JFK    MCI       2      -12   
##  2 LGA    GRR      11      -11   
##  3 EWR    MYR       4      -10   
##  4 LGA    GRR       3      -10   
##  5 LGA    MHT       2      -10   
##  6 LGA    LEX      11       -9   
##  7 LGA    ORF       5       -9   
##  8 LGA    ROC       1       -8   
##  9 LGA    SDF       9       -7.16
## 10 LGA    RIC       3       -7   
## # ... with 2,303 more rows

4.9. Ringkasan (summary) dan Group

group_by() dan summarise() digunakan untuk menghitung statistik berdasarkan grup yg disebutkan pada fungi group_by().

flights %>% 
  group_by(origin, dest) %>% 
  summarise(rata2_delay = mean(dep_delay, na.rm = TRUE))
## # A tibble: 224 x 3
## # Groups:   origin [3]
##    origin dest  rata2_delay
##    <chr>  <chr>       <dbl>
##  1 EWR    ALB         23.6 
##  2 EWR    ANC         12.9 
##  3 EWR    ATL         15.5 
##  4 EWR    AUS         11.5 
##  5 EWR    AVL          8.62
##  6 EWR    BDL         17.7 
##  7 EWR    BNA         17.7 
##  8 EWR    BOS         12.5 
##  9 EWR    BQN         23.9 
## 10 EWR    BTV         17.8 
## # ... with 214 more rows

Hasil dari summarise() adalah sebuah data frame/tibble. Maka dari itu, sebaiknya berikan nama pada hasil summarise(). rata2_delay adalah nama variabel hasil dari mean().

flights %>% 
  group_by(origin, dest) %>% 
  summarise(rata2_delay = mean(dep_delay, na.rm = TRUE)) %>% 
  spread(key = origin, value = rata2_delay) # soon replaced with pivot_wider()
## # A tibble: 105 x 4
##    dest    EWR   JFK   LGA
##    <chr> <dbl> <dbl> <dbl>
##  1 ABQ   NA    13.7   NA  
##  2 ACK   NA     6.46  NA  
##  3 ALB   23.6  NA     NA  
##  4 ANC   12.9  NA     NA  
##  5 ATL   15.5  10.5   11.4
##  6 AUS   11.5  14.0   NA  
##  7 AVL    8.62 NA     -2.6
##  8 BDL   17.7  NA     NA  
##  9 BGR   NA    NA     19.5
## 10 BHM   NA     7     29.8
## # ... with 95 more rows

spread() membuat variabel baru dari isi sebuah variabel yang disebutkan pada argumen key = sebagai nama variabel, dan nilai dari variabel-variabel baru tersebut adalah nilai dari variabel yang disebutkan di argumen value =.

Note: pada saat tutorial ini dibuat, package tidyr masih menggunakan fungsi spread() dan gather() untuk transformasi data frame. Namun pembuat package tidyr sudah berencana untuk menggantinya dengan nama fungsi baru, yaitu pivot_wider() dan pivot_longer().

flights %>% 
  group_by(origin, dest) %>% 
  summarise(rata2_delay = mean(dep_delay, na.rm = TRUE)) %>% 
  spread(key = origin, value = rata2_delay) %>% # soon replaced with pivot_wider()
  gather(key = origin, value = rata2_delay, -dest) # soon replaced with pivot_longer()
## # A tibble: 315 x 3
##    dest  origin rata2_delay
##    <chr> <chr>        <dbl>
##  1 ABQ   EWR          NA   
##  2 ACK   EWR          NA   
##  3 ALB   EWR          23.6 
##  4 ANC   EWR          12.9 
##  5 ATL   EWR          15.5 
##  6 AUS   EWR          11.5 
##  7 AVL   EWR           8.62
##  8 BDL   EWR          17.7 
##  9 BGR   EWR          NA   
## 10 BHM   EWR          NA   
## # ... with 305 more rows
tb <- flights %>%
  group_by(month) %>% 
  count()

plot(tb$month, tb$n, "l")

tb <- flights %>%
  group_by(day) %>% 
  count()

plot(tb$day, tb$n, "l")

tb <- flights %>%
  mutate(dates = as.Date(paste(year, month, day, sep = "-"), format = "%Y-%m-%d")) %>%
  group_by(dates) %>% 
  count()
plot(tb$dates, tb$n, "l")

Fungsi paste berfungsi untuk menggabungkan (concate) dua buah nilai atau vector menjadi character dengan pemisah antar nilai tersebut adalah . Misalnya

paste("nilai ini", 9)
## [1] "nilai ini 9"

Untuk mengganti pemisahnya Anda dapat menyebutkannya pada argumen sep =. Misalnya Anda ingin menggunakan pemisah tanda -, maka

paste("nilai ini", 9, sep = "-")
## [1] "nilai ini-9"

Fungsi as.Date() melakukan konversi dari sebuah character menjadi nilai tanggal (date-value) di R. Format tanggal default di R adalah yyyy-mm-dd, namun di R menggunakan format %Y-%m-%d untuk 2019-05-10. Selebihnya Anda dapat melihatnya dengan ?as.Date.

4.10. Merge/Join Tabel

Dalam dunia nyata, terutama di dunia kerja dan perusahaan, jarang sekali data yang digunakan hanya berasal dari satu tabel atau file. Biasanya ada tabel-tabel lain yang harus digunakan untuk mendukung analisis data. Misalnya di bank, di database minimal ada tabel master_customer yang berisi data demografi (nama, tempat & tanggal lahir, alamat, dst), dan transaction yang berisi data transaksi nasabah.

Pada bagian tutorial ini, akan membahas penggunaan beberapa tabel yang sudah dijelaskan di bagian awal mengenai data. Ada 7 dataset yang dapat digunakan. Mungkin untuk melakukan analisis dan mendapatkan hasilnya Anda tidak membutuhkan semuanya.

Dari ketujuh tabel, relasinya digambarkan seperti gambar di bawah ini.

Diagram Relasi Tabel

Diagram Relasi Tabel

  • flights dihubungkan dengan planes via satu variabel, tailnum.

  • flights dihubungkan dengan airlines melaui variabel carrier.

  • flights dihubungkan dengan airports dengan dua cara: via variabel origin dengan variabel faa dan dest dengan variabel faa.

  • flights dihubungkan dengan weather via origin (lokasi), dan year, month, day dan hour.

  • flights dihubungkan dengan prices via year, month, day, hour, flight, origin, dest, sched_dep_time, dan tailnum.

  • flights dihubungkan dengan specialdays via variabel year, month, dan day.

Berikut fungsi untuk merge/join menggunakan package dplyr dan perbandingannya dengan SQL.

dplyr SQL
inner_join(x, y, by = c("a" = "b") SELECT * FROM x INNER JOIN y ON x.a = y.b
left_join(x, y, by = c("a" = "b")) SELECT * FROM x LEFT OUTER JOIN y ON x.a = y.b
right_join(x, y, by = c("a" = "b")) SELECT * FROM x RIGHT OUTER JOIN y ON x.a = y.b
full_join(x, y, by = c("a" = "b")) SELECT * FROM x FULL OUTER JOIN y ON x.a = y.b

Catatan: “INNER” dan “OUTER” pada SQL adalah opsional, dan lebih sering tidak dituliskan.

Berikut ilustrasi untuk menjelaskan merge/join.

Misalkan ada dua buah tabel, x dan y yang masing-masing mempunyai 2 variabel seperti pada gambar di bawah ini. Variabel pertama adalah key dan variabel kedua adalah val.

tabel ilustrasi

Tabel x dan y

4.10.1. Inner Join

Ketika melakukan proses inner_join maka akan diambil nilai yang sama dari key yang digunakan dari kedua tabel tersebut. Pada ilustrasi di bawah ini, digunakan inner_join untuk menggabungkan tabel x dan y. Dari kedua tabel tersebut, nilai key yang ada di tabel x dan y adalah 1 dan 2. Maka hasilnya adalah diambil baris data yang sama di kedua tabel tersebut, yaitu nilai key 1 dan 2.

x %>% 
  inner_join(y, by = "key")

Jika ada variabel lain selain key yang namanya sama, maka dibelakang masing-masing nama variabel tersebut akan ditambahkan suffix. suffix secara default adalah suffix = c(".x", ".y"). Artinya karena di masing-masing tabel ada variabel yang sama dan variabel ini bukan sebuah key pada saat join, yaitu val, maka setelah proses join nama val akan diganti menjadi val.x untuk variabel yang berasal dari tabel x dan val.y yang berasal dari tabel y.

Jika ingin mengganti suffix, Anda dapat menggunakan argumen suffix pada fungsi join.

x %>% 
  inner_join(y, by = "key", suffix = c("_x", "_y"))

Ilustrasi Inner Join

Ilustrasi Inner Join

tbl1 <- flights %>%
    inner_join(weather, by = c("year", "month", "day", "hour", "origin", "time_hour"))
glimpse(tbl1)
## Observations: 335,220
## Variables: 28
## $ year           <dbl> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013,...
## $ month          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ day            <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ dep_time       <dbl> 517, 533, 542, 544, 554, 554, 555, 557, 557, 55...
## $ sched_dep_time <dbl> 515, 529, 540, 545, 600, 558, 600, 600, 600, 60...
## $ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2...
## $ arr_time       <dbl> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 7...
## $ sched_arr_time <dbl> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 7...
## $ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -...
## $ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV",...
## $ flight         <dbl> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79...
## $ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN...
## $ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR"...
## $ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL"...
## $ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138...
## $ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 94...
## $ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,...
## $ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ time_hour      <chr> "2013-01-01 05:00:00", "2013-01-01 05:00:00", "...
## $ temp           <dbl> 39.02, 39.92, 39.02, 39.02, 39.92, 39.02, 37.94...
## $ dewp           <dbl> 28.04, 24.98, 26.96, 26.96, 24.98, 28.04, 28.04...
## $ humid          <dbl> 64.43, 54.81, 61.63, 61.63, 54.81, 64.43, 67.21...
## $ wind_dir       <dbl> 260, 250, 260, 260, 260, 260, 240, 260, 260, 26...
## $ wind_speed     <dbl> 12.65858, 14.96014, 14.96014, 14.96014, 16.1109...
## $ wind_gust      <dbl> NA, 21.86482, NA, NA, 23.01560, NA, NA, 23.0156...
## $ precip         <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ pressure       <dbl> 1011.9, 1011.4, 1012.1, 1012.1, 1011.7, 1011.9,...
## $ visib          <dbl> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,...
head(tbl1)
## # A tibble: 6 x 28
##    year month   day dep_time sched_dep_time dep_delay arr_time
##   <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
## 1  2013     1     1      517            515         2      830
## 2  2013     1     1      533            529         4      850
## 3  2013     1     1      542            540         2      923
## 4  2013     1     1      544            545        -1     1004
## 5  2013     1     1      554            600        -6      812
## 6  2013     1     1      554            558        -4      740
## # ... with 21 more variables: sched_arr_time <dbl>, arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>, temp <dbl>, dewp <dbl>, humid <dbl>, wind_dir <dbl>,
## #   wind_speed <dbl>, wind_gust <dbl>, precip <dbl>, pressure <dbl>,
## #   visib <dbl>

Karena semua variabel yang namanya sama di data frame flights dan weather digunakan sebagai key maka tidak ada variabel yang ditambahkan suffix.

4.10.2. Left, Right and Full Outer Join

Perhatikan ilustrasi untuk left, right, dan full outer join.

Ilustrasi Inner Join

Ilustrasi Left, Right dan Full Outer Join

Pada kesempatan ini hanya akan dibahas mengenai left join. Pada dasarnya left_join() mengambil semua baris yang ada di tabel sebelah kiri (LHS), dalam ilustrasi di atas adalah tabel x, dan mencari nilai yang ada pasangannya di tabel sebelah kanan (RHS), yaitu tabel y.

Jika nilai dari variabel key di tabel x tidak ada pasangannya di tabel y maka nilai val untuk baris tersebut akan menjadi missing value atau NA.

tbl2 <- flights %>%
    left_join(airports, by = c("origin" = "faa")) %>%
    left_join(airports, by = c("dest" = "faa"), suffix = c("_origin", "_dest"))
glimpse(tbl2)
## Observations: 336,776
## Variables: 33
## $ year           <dbl> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013,...
## $ month          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ day            <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ dep_time       <dbl> 517, 533, 542, 544, 554, 554, 555, 557, 557, 55...
## $ sched_dep_time <dbl> 515, 529, 540, 545, 600, 558, 600, 600, 600, 60...
## $ dep_delay      <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2...
## $ arr_time       <dbl> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 7...
## $ sched_arr_time <dbl> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 7...
## $ arr_delay      <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -...
## $ carrier        <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV",...
## $ flight         <dbl> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79...
## $ tailnum        <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN...
## $ origin         <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR"...
## $ dest           <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL"...
## $ air_time       <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138...
## $ distance       <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 94...
## $ hour           <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5,...
## $ minute         <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ time_hour      <chr> "2013-01-01 05:00:00", "2013-01-01 05:00:00", "...
## $ name_origin    <chr> "Newark Liberty Intl", "La Guardia", "John F Ke...
## $ lat_origin     <dbl> 40.69250, 40.77725, 40.63975, 40.63975, 40.7772...
## $ lon_origin     <dbl> -74.16867, -73.87261, -73.77893, -73.77893, -73...
## $ alt_origin     <dbl> 18, 22, 13, 13, 22, 18, 18, 22, 13, 22, 13, 13,...
## $ tz_origin      <dbl> -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5,...
## $ dst_origin     <chr> "A", "A", "A", "A", "A", "A", "A", "A", "A", "A...
## $ tzone_origin   <chr> "America/New_York", "America/New_York", "Americ...
## $ name_dest      <chr> "George Bush Intercontinental", "George Bush In...
## $ lat_dest       <dbl> 29.98443, 29.98443, 25.79325, NA, 33.63672, 41....
## $ lon_dest       <dbl> -95.34144, -95.34144, -80.29056, NA, -84.42807,...
## $ alt_dest       <dbl> 97, 97, 8, NA, 1026, 668, 9, 313, 96, 668, 19, ...
## $ tz_dest        <dbl> -6, -6, -5, NA, -5, -6, -5, -5, -5, -6, -5, -5,...
## $ dst_dest       <chr> "A", "A", "A", NA, "A", "A", "A", "A", "A", "A"...
## $ tzone_dest     <chr> "America/Chicago", "America/Chicago", "America/...
head(tbl2)
## # A tibble: 6 x 33
##    year month   day dep_time sched_dep_time dep_delay arr_time
##   <dbl> <dbl> <dbl>    <dbl>          <dbl>     <dbl>    <dbl>
## 1  2013     1     1      517            515         2      830
## 2  2013     1     1      533            529         4      850
## 3  2013     1     1      542            540         2      923
## 4  2013     1     1      544            545        -1     1004
## 5  2013     1     1      554            600        -6      812
## 6  2013     1     1      554            558        -4      740
## # ... with 26 more variables: sched_arr_time <dbl>, arr_delay <dbl>,
## #   carrier <chr>, flight <dbl>, tailnum <chr>, origin <chr>, dest <chr>,
## #   air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
## #   time_hour <chr>, name_origin <chr>, lat_origin <dbl>,
## #   lon_origin <dbl>, alt_origin <dbl>, tz_origin <dbl>, dst_origin <chr>,
## #   tzone_origin <chr>, name_dest <chr>, lat_dest <dbl>, lon_dest <dbl>,
## #   alt_dest <dbl>, tz_dest <dbl>, dst_dest <chr>, tzone_dest <chr>

Jika diperhatikan, ada beberapa variabel dari tbl2 yang namanya menggunakan _origin dan _dest. Hal ini menunjukkan ada variabel yang namanya sama dari hasil left_join() pertama dan kedua, yaitu nama variabel dari data frame airports. Karena dua kali join maka akan ada nama variabel yang sama sehingga namanya ditambahkan suffix.

5. Latihan

Buatlah analisis data untuk kebutuhan berikut!

  1. Penerbangan dengan keterlambatan kedatangannya dua jam atau lebih.
  2. Perbandingan penerbangan ke Houston (IAH atau HOU) berdasarkan bandara asalnya per bulan. Hint: Anda dapat gunakan operator %in%.
  3. Penerbangan dioperasikan oleh United, American, atau Delta. Hint: Anda dapat gunakan operator %in%.
  4. Penerbangan di musim panas (July, August, and September). Hint: Anda dapat gunakan fungsi between().
  5. Kedatangan yang terlambat datang lebih dari dua jam, tetapi tidak berangkat terlambat.
  6. Penerbangan yang delay paling tidak satu jam, tetapi terbang lebih dari 30 menit.
  7. Penerbangan yang berangkat antara tengah malam dan jam 6 pagi (inclusive).
  8. Berapa banyak penerbangan yang nilai tailnum-nya missing? Apa maksud dari baris-baris data ini?
  9. Berapa banyak penerbangan yang nilai dep_time-nya missing? Variable apalagi selain itu yang missing? Apa maksud dari baris-baris data ini?
  10. Bagaimana hubungan penerbangan delay dikarenakan cuaca dan kondisi pesawat?

———————– Semoga Bermanfaat ———————–

Contact me: Aep Hidayatuloh

Email: GitHub: https://github.com/aephidayatuloh