Factor adalah salah satu tipe struktur data dalam R bersama dengan vector, list, matriks, dan dataframe. Factor adalah jenis struktur data satu dimensi yang khusus digunakan untuk menampung data tipe kategorikal. Kebiasaan ku hingga saat ini adalah langsung mengubah data tipe character menjadi factor karena kemudahan untuk manipulasinya.
Untuk dapat memanfaatkan fungsi factor secara optimal, kita akan menggunakan tool bernama forcats yang juga berada dalam package ‘tidyverse’
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.1.2
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5 v purrr 0.3.4
## v tibble 3.1.4 v dplyr 1.0.7
## v tidyr 1.1.4 v stringr 1.4.0
## v readr 2.0.2 v forcats 0.5.1
## Warning: package 'tidyr' was built under R version 4.1.2
## Warning: package 'dplyr' was built under R version 4.1.2
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
Pernah kita bahas sebelumnya, tapi ini ada rangkuman singkat soal factor
# Membuat factor
x1 <- c("TS","SD","SMP","SMA","S1","S2","S3")
x2 <- c("SMP","SMP","SMA","TS","S2","S1","S1")
pendidikan <- factor(x2, levels = x1)
pendidikan
## [1] SMP SMP SMA TS S2 S1 S1
## Levels: TS SD SMP SMA S1 S2 S3
# akses ke level
levels(pendidikan)
## [1] "TS" "SD" "SMP" "SMA" "S1" "S2" "S3"
# Menjadi level sebagaimana kemunculan data
pendidikan2 <- factor(x2, levels = unique(x2))
pendidikan2
## [1] SMP SMP SMA TS S2 S1 S1
## Levels: SMP SMA TS S2 S1
Mari kita coba dengan data lain. Di sini kita menggunakan package data gss_cat
gss_cat
## # A tibble: 21,483 x 9
## year marital age race rincome partyid relig denom tvhours
## <int> <fct> <int> <fct> <fct> <fct> <fct> <fct> <int>
## 1 2000 Never married 26 White $8000 to 9999 Ind,nea~ Prote~ South~ 12
## 2 2000 Divorced 48 White $8000 to 9999 Not str~ Prote~ Bapti~ NA
## 3 2000 Widowed 67 White Not applicable Indepen~ Prote~ No de~ 2
## 4 2000 Never married 39 White Not applicable Ind,nea~ Ortho~ Not a~ 4
## 5 2000 Divorced 25 White Not applicable Not str~ None Not a~ 1
## 6 2000 Married 25 White $20000 - 24999 Strong ~ Prote~ South~ NA
## 7 2000 Never married 36 White $25000 or more Not str~ Chris~ Not a~ 3
## 8 2000 Divorced 44 White $7000 to 7999 Ind,nea~ Prote~ Luthe~ NA
## 9 2000 Married 44 White $25000 or more Not str~ Prote~ Other 0
## 10 2000 Married 47 White $25000 or more Strong ~ Prote~ South~ 3
## # ... with 21,473 more rows
Dalam bentuk tibble, kita akan agak sulit untuk melihat levels yg ada secara langsung. Untuk melihatnya, kita bisa mengakali dengan menggunakan fungsi count() atau plot bar.
gss_cat %>% count(race)
## # A tibble: 3 x 2
## race n
## <fct> <int>
## 1 Other 1959
## 2 Black 3129
## 3 White 16395
Oke, kita jadi tahu bahwa dalam variabel race, ada 3 level (other, black, dan white).
gss_cat %>% ggplot() + geom_bar(aes(x = race)) + scale_x_discrete(drop = FALSE)
Exercise 1. eksplor distribusi rincome (reported income). Apa yang membuat plot barnya agak susah untuk dipahami?
gss_cat %>% count(rincome)
## # A tibble: 16 x 2
## rincome n
## <fct> <int>
## 1 No answer 183
## 2 Don't know 267
## 3 Refused 975
## 4 $25000 or more 7363
## 5 $20000 - 24999 1283
## 6 $15000 - 19999 1048
## 7 $10000 - 14999 1168
## 8 $8000 to 9999 340
## 9 $7000 to 7999 188
## 10 $6000 to 6999 215
## 11 $5000 to 5999 227
## 12 $4000 to 4999 226
## 13 $3000 to 3999 276
## 14 $1000 to 2999 395
## 15 Lt $1000 286
## 16 Not applicable 7043
Analisa rerata waktu menonton TV berdasarkan agama
relig_summary <- gss_cat %>% group_by(relig) %>%
summarise(
age = mean(age, na.rm = TRUE),
tvhours = mean(tvhours, na.rm = TRUE),
jumlah = n()
)
relig_summary
## # A tibble: 15 x 4
## relig age tvhours jumlah
## <fct> <dbl> <dbl> <int>
## 1 No answer 49.5 2.72 93
## 2 Don't know 35.9 4.62 15
## 3 Inter-nondenominational 40.0 2.87 109
## 4 Native american 38.9 3.46 23
## 5 Christian 40.1 2.79 689
## 6 Orthodox-christian 50.4 2.42 95
## 7 Moslem/islam 37.6 2.44 104
## 8 Other eastern 45.9 1.67 32
## 9 Hinduism 37.7 1.89 71
## 10 Buddhism 44.7 2.38 147
## 11 Other 41.0 2.73 224
## 12 None 41.2 2.71 3523
## 13 Jewish 52.4 2.52 388
## 14 Catholic 46.9 2.96 5124
## 15 Protestant 49.9 3.15 10846
relig_summary %>% ggplot() + geom_point(aes(x = tvhours, y = relig))
Sayangnya, plot yang terlihat di atas tidak memberikan hasil yang bisa dimaknai dengan jelas. Mungkin ada yang bisa kita lakukan? Bagaimana kalau kita melakukan sedikit perubahan pada urutan level agamanya?
relig_summary %>% ggplot() + geom_point(aes(tvhours, fct_reorder(relig,tvhours)))
Nah, mulai terlihat polanya kan? Di sini kita bisa menghipotesiskan bahwa ada perbedaan rata-rata antara orang yang memiliki jalur keagamaan tertentu dengan yang tidak jelas keagamaannya terhadap lama mereka mengonsumsi televisi.
Di sini kita menggunakan fct_reorder() untuk mengurutkan level ‘relig’ berdasarkan nilai ‘tvhours’. Note : fct_inorder() digunakan untuk mengatur urutan level berdasarkan tampilan pertama pada factor, frequency factor itu sendiri, atau numeric order.
Exercise 2
relig_general <- gss_cat %>% group_by(relig) %>% summarise(jumlah = n()) %>%
arrange(desc(jumlah))
relig_general
## # A tibble: 15 x 2
## relig jumlah
## <fct> <int>
## 1 Protestant 10846
## 2 Catholic 5124
## 3 None 3523
## 4 Christian 689
## 5 Jewish 388
## 6 Other 224
## 7 Buddhism 147
## 8 Inter-nondenominational 109
## 9 Moslem/islam 104
## 10 Orthodox-christian 95
## 11 No answer 93
## 12 Hinduism 71
## 13 Other eastern 32
## 14 Native american 23
## 15 Don't know 15
relig_general %>% ggplot() + geom_col(aes(fct_reorder(relig,jumlah),jumlah)) + coord_flip()
Untuk bidang politik ‘partyid’
jawab :
party_summary <- gss_cat %>% group_by(partyid) %>% summarise(jumlah = n())
party_summary %>% ggplot() + geom_col(aes(fct_reorder(partyid,jumlah),jumlah))+
coord_flip()
Contoh lain :
by_age <- gss_cat %>%
filter(!is.na(age)) %>%
count(age, marital) %>%
group_by(age) %>%
mutate(prop = n/sum(n))
by_age
## # A tibble: 351 x 4
## # Groups: age [72]
## age marital n prop
## <int> <fct> <int> <dbl>
## 1 18 Never married 89 0.978
## 2 18 Married 2 0.0220
## 3 19 Never married 234 0.940
## 4 19 Divorced 3 0.0120
## 5 19 Widowed 1 0.00402
## 6 19 Married 11 0.0442
## 7 20 Never married 227 0.904
## 8 20 Separated 1 0.00398
## 9 20 Divorced 2 0.00797
## 10 20 Married 21 0.0837
## # ... with 341 more rows
Pembuatan grafik
by_age %>% ggplot() + geom_line(aes(age,prop,color=marital), na.rm = T)
fct_infreq adalah fungsi forcats yang mengatur level factor berdasarkan frequencinya. ini sangat berguna digunakan untuk geom_bar() yang hanya memiliki satu variabel diskrit.
gss_cat %>% mutate(relig = relig %>% fct_infreq()) %>% ggplot() +
geom_bar(aes(relig))
Fungsi ini digunakan untuk mengubah value level. (bukan levelnya, kecuali level dan valuenya memang sama.)
gss_cat %>% mutate(partyid = fct_recode(partyid,
newvalue1 = level1,
newvalue2 = level2,
......))
Dengan fct_recode, kita bisa mengubah value level, atau collapse level.
Nilai datetime merupakan salah satu data yang cukup tricky untuk diolah. Hal ini karena faktor fisikal, geopolitik, dan adanya DST (Day Saving Time) yang membuat beberapa perbedaan rentang waktu.
Untuk mengolah datetime, kita akan menggunakan package ‘lubridate’. Meski merupakan bagian dari tidyverse, kita tetap harus meload library ini, karena datetime bukan core dari tidyverse.
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
Untuk pembahasan di sini, kita akan menggunakan paket dataset ‘nycflights13’
Ada tiga tipe date/time : * Date * Time * Datetime Pada pembahasan ini, kita akan coba fokus pada data ‘date’ dan ‘datetime’
today()
## [1] "2022-01-03"
now()
## [1] "2022-01-03 00:43:17 +07"
Ada tiga cara yang bisa dilakukan untuk membuat date/time : * Dengan string * dari komponen individu date-time * Dari objek date-time yang sudah ada
Masih ingat dengan parsing datetime? itu adalah metode untuk mengubah string menjadi objek datetime. Cara lain adalah dengan menggunakan lubridate; tulis identifikasi objek date dan time sesuai urutan yang kita inginkan (y untuk tahun, m untuk bulan dan d untuk tanggal), diikuti dengan value yang ingin kita ubah.
ymd("2017-01-31")
## [1] "2017-01-31"
mdy("12-02-2021")
## [1] "2021-12-02"
dmy("24-1-2022")
## [1] "2022-01-24"
parse_date_time("1/4/2022", "dmy")
## [1] "2022-04-01 UTC"
parse_date_time("01042022", "dmy")
## [1] "2022-04-01 UTC"
mdy(01012022)
## [1] "2022-01-01"
ymd_hm(1101220811)
## [1] "2011-01-22 08:11:00 UTC"
Lihat? baik parse dan fungsi lubridate memiliki fungsi yang sama, hanya saja untuk fungsi dari lubridate dapat digunakan saat variabel bukan string sekalipun.
Selain dari string, kita mungkin akan menemui data tanggal dan waktu yang terpecah dalam beberapa tabel, seperti yang kita temui dalam data flights.
library(nycflights13)
## Warning: package 'nycflights13' was built under R version 4.1.2
head(flights)
## # A tibble: 6 x 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## # ... with 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## # hour <dbl>, minute <dbl>, time_hour <dttm>
flights %>% select(year, month, day, hour, minute)
## # A tibble: 336,776 x 5
## year month day hour minute
## <int> <int> <int> <dbl> <dbl>
## 1 2013 1 1 5 15
## 2 2013 1 1 5 29
## 3 2013 1 1 5 40
## 4 2013 1 1 5 45
## 5 2013 1 1 6 0
## 6 2013 1 1 5 58
## 7 2013 1 1 6 0
## 8 2013 1 1 6 0
## 9 2013 1 1 6 0
## 10 2013 1 1 6 0
## # ... with 336,766 more rows
Untuk mendapatkan data datetime dari nilai yang terpecah ini, kita bisa menggunakan make_date() untuk membuat date, atau make_datetime() untuk date/time.
flights %>% select(year, month, day, hour, minute) %>% mutate(
datetime = make_datetime(year, month, day, hour, minute))
## # A tibble: 336,776 x 6
## year month day hour minute datetime
## <int> <int> <int> <dbl> <dbl> <dttm>
## 1 2013 1 1 5 15 2013-01-01 05:15:00
## 2 2013 1 1 5 29 2013-01-01 05:29:00
## 3 2013 1 1 5 40 2013-01-01 05:40:00
## 4 2013 1 1 5 45 2013-01-01 05:45:00
## 5 2013 1 1 6 0 2013-01-01 06:00:00
## 6 2013 1 1 5 58 2013-01-01 05:58:00
## 7 2013 1 1 6 0 2013-01-01 06:00:00
## 8 2013 1 1 6 0 2013-01-01 06:00:00
## 9 2013 1 1 6 0 2013-01-01 06:00:00
## 10 2013 1 1 6 0 2013-01-01 06:00:00
## # ... with 336,766 more rows
Sekarang, kita terapkan cara ini untuk memodifikasi data dept dan arrival pada flights. Seperti yang kalian perhatikan, data waktu itu sedikit aneh. Kita perlu mengubahnya sedikit.
Dari tampilan data, kita tahu bahwa ada seluruh dept dan arr time (juga schedule) ditulis dalam waktu jam dan menit yg ditulis gandeng renteng. Untuk mengatasi hal tersebut, valua keempat kolom tersebut harus dimodulasikan dengan 100.
make_datetime_100 <- function(year, month, day, time) {
make_datetime(year, month, day, time%/%100, time%%100)
}
flights_dt <- flights %>%
filter(!is.na(dep_time),!is.na(arr_time)) %>%
mutate(
dep_time = make_datetime_100(year,month,day, dep_time),
arr_time = make_datetime_100(year,month,day,arr_time),
sched_dep_time = make_datetime_100(year,month,day,sched_dep_time),
sched_arr_time = make_datetime_100(year,month, day, sched_arr_time)
) %>%
select(origin, dest, ends_with("delay"),ends_with("time"))
flights_dt
## # A tibble: 328,063 x 9
## origin dest dep_delay arr_delay dep_time sched_dep_time
## <chr> <chr> <dbl> <dbl> <dttm> <dttm>
## 1 EWR IAH 2 11 2013-01-01 05:17:00 2013-01-01 05:15:00
## 2 LGA IAH 4 20 2013-01-01 05:33:00 2013-01-01 05:29:00
## 3 JFK MIA 2 33 2013-01-01 05:42:00 2013-01-01 05:40:00
## 4 JFK BQN -1 -18 2013-01-01 05:44:00 2013-01-01 05:45:00
## 5 LGA ATL -6 -25 2013-01-01 05:54:00 2013-01-01 06:00:00
## 6 EWR ORD -4 12 2013-01-01 05:54:00 2013-01-01 05:58:00
## 7 EWR FLL -5 19 2013-01-01 05:55:00 2013-01-01 06:00:00
## 8 LGA IAD -3 -14 2013-01-01 05:57:00 2013-01-01 06:00:00
## 9 JFK MCO -3 -8 2013-01-01 05:57:00 2013-01-01 06:00:00
## 10 LGA ORD -2 8 2013-01-01 05:58:00 2013-01-01 06:00:00
## # ... with 328,053 more rows, and 3 more variables: arr_time <dttm>,
## # sched_arr_time <dttm>, air_time <dbl>
Dengan ini, kita bisa menganalisa data lebih baik. Contoh kita ingin melihat distribusi waktu departur, maka :
flights_dt %>% ggplot() + geom_freqpoly(aes(dep_time),
binwidth = 86400) # 86400 jumlah detik dalam 1 hari
Seluruh data datetime akan dihitung berdasarkan satuan terkecilnya, yaitu detik. Seperti pada binwidth di atas, kita memberikan nilai 86400, karena itu lah jumlah detik dalam satu hari, yang artinya kita membagi dept_time berdasarkan data harian.
Contoh lain di bawah ini adalah misal kita ingin membagi atau fokus melihat distribusi dep_time dalam satu hari di tanggal 1 Januari 2013.
flights_dt %>% filter(dep_time < ymd(20130102)) %>%
ggplot() + geom_freqpoly(aes(dep_time), binwidth = 600)
Di sini, kita membagi waktu dep_time per 10 menit (1 menit = 60 detik, 10 menit = 600 detik).
Ada kalanya kita juga ingin mengubah tipe dari datetime ke date atau dari date ke datetime. Untuk ini, kita bisa menggunakan as_datetime() atau as_date().
ymd(c("2010-10-10","banana"))
## Warning: 1 failed to parse.
## [1] "2010-10-10" NA
Jawab: Secara otomatis, output yang dihasilkan adalah NA.
d1 <- "January 1, 2021"
d2 <- "2015-Mar-07"
d3 <- "06-Jun-2017"
d4 <- c("August 19 (2015)","July 1 (2015)")
d5 <- "12/30/14" # Des 30, 2014
# Jawaban
mdy(d1)
## [1] "2021-01-01"
ymd(d2)
## [1] "2015-03-07"
dmy(d3)
## [1] "2017-06-06"
mdy(d4)
## [1] "2015-08-19" "2015-07-01"
mdy(d5)
## [1] "2014-12-30"
parse_date_time(d1, "%B %d, %Y")
## [1] "2021-01-01 UTC"
parse_date_time(d2, "%Y-%b-%d")
## [1] "2015-03-07 UTC"
parse_date_time(d3, "%d-%b-%Y")
## [1] "2017-06-06 UTC"
parse_date_time(d4, "%B %d (%Y)")
## [1] "2015-08-19 UTC" "2015-07-01 UTC"
parse_date_time(d5, "%m/%d/%y")
## [1] "2014-12-30 UTC"
Bagian ini akan fokus tentang pengambilan dan pengolahan komponen date time secara aritmatik. Berikut adalah fungsi-fungsi yang digunakan untuk mendapatkan komponen hari. * date() untuk mendapatkan komponen tanggal * year() untuk mendapatkan komponen tahun * month() untuk mendapatkan komponen bulan * note : tulis month(label = T, abbr = F) untuk mendapat output nama penuh bulan * day() untuk mendapatkan komponen hari dalam satu bulan itu. * yday() untuk mendapatkan komponen hari dalam satu tahun (hari keberapa dalam satu tahun) * wday() untuk mendapatkan komponen hari dalam satu minggu. * qday() untuk mendapatkan komponen hari dalam satu quarter * hour() untuk mendapatkan komponen jam * minute() untuk mendapat komponen menit * second() untuk mendapatkan komponen detik * tz() untuk mendapatkan komponen zona waktu * week() untuk mendapatkan komponen minggu dalam satu tahun. * isoweek() untuk mendapat komponen minggu dalam ISO 8601 standart (ISO 8601 adalah kalender standart di mana tidak ada DST, sehingga seluruh minggu berisi 7 hari, dengan tidak adanya minggu yang lewat dari satu tahun. ) * epiweek() untuk mendpat komponen minggu epidemiological (standart kalender yang digunakan ahli epidemi) * quarter(), untuk mendapatkan komponen kuartal dari datetime yg ada * semester(), untuk mendapatkan komponen semester * am() untuk melakukan tes pada datetime, apakah termasuk dalam am atau tidak * pm() untuk melakukan tes, menguji apakah datetime termasuk pm * dst(), untuk menguji apakah datetime termasuk daylight saving time * leap_year(), untuk menguji apakah datetime masuk dalam tahun kabisat * update(obj datetime, …), mengubah value objek datetime.
contoh :
dt <- now()
# Contoh seluruh set dan get timedate component
date(dt)
## [1] "2022-01-03"
year(dt)
## [1] 2022
month(dt, label = T, abbr = FALSE)
## [1] January
## 12 Levels: January < February < March < April < May < June < ... < December
day(dt)
## [1] 3
week(dt)
## [1] 1
wday(dt, label = T, abbr = FALSE)
## [1] Monday
## 7 Levels: Sunday < Monday < Tuesday < Wednesday < Thursday < ... < Saturday
yday(dt)
## [1] 3
qday(dt)
## [1] 3
hour(dt)
## [1] 0
minute(dt)
## [1] 43
second(dt)
## [1] 33.51394
tz(dt)
## [1] ""
isoweek(dt)
## [1] 1
epiweek(dt)
## [1] 1
quarter(dt)
## [1] 1
semester(dt)
## [1] 1
am(dt)
## [1] TRUE
pm(dt)
## [1] FALSE
leap_year(dt)
## [1] FALSE
dst(dt)
## [1] FALSE
Kembali pada contoh data ‘flights’, sekarang kita bisa melakukan analisa dist departure time dalam satu minggu menggunakan fungsi ‘wday’ (hari dalam satu minggu)
flights_dt %>%
mutate(wday = wday(dep_time, label = T)) %>%
ggplot() + geom_bar(aes(wday))
Di sini kita bisa ambil kesimpulan sementara bahwa ada lebih banyak penerbangan pada weekday daripada weekend. (Akan lebih baik lagi jika seandainya kita bisa melihat timeline harian dari minggu ke minggu)
Percobaan grafik (analisa dep_time harian di bulan Januari 2013)
flights_try <- flights_dt %>%
mutate(month = month(dep_time, label=T),
week = week(dep_time),
wday = wday(dep_time, label = T)) %>%
filter(month == "Jan")
flights_try
## # A tibble: 26,468 x 12
## origin dest dep_delay arr_delay dep_time sched_dep_time
## <chr> <chr> <dbl> <dbl> <dttm> <dttm>
## 1 EWR IAH 2 11 2013-01-01 05:17:00 2013-01-01 05:15:00
## 2 LGA IAH 4 20 2013-01-01 05:33:00 2013-01-01 05:29:00
## 3 JFK MIA 2 33 2013-01-01 05:42:00 2013-01-01 05:40:00
## 4 JFK BQN -1 -18 2013-01-01 05:44:00 2013-01-01 05:45:00
## 5 LGA ATL -6 -25 2013-01-01 05:54:00 2013-01-01 06:00:00
## 6 EWR ORD -4 12 2013-01-01 05:54:00 2013-01-01 05:58:00
## 7 EWR FLL -5 19 2013-01-01 05:55:00 2013-01-01 06:00:00
## 8 LGA IAD -3 -14 2013-01-01 05:57:00 2013-01-01 06:00:00
## 9 JFK MCO -3 -8 2013-01-01 05:57:00 2013-01-01 06:00:00
## 10 LGA ORD -2 8 2013-01-01 05:58:00 2013-01-01 06:00:00
## # ... with 26,458 more rows, and 6 more variables: arr_time <dttm>,
## # sched_arr_time <dttm>, air_time <dbl>, month <ord>, week <dbl>, wday <ord>
flights_try %>% ggplot() + geom_bar(aes(week, fill = wday), position = "dodge")
Di sini, kita menampilkan bahwa pada penerbangan selama bulan Januari, terdapat pola konsisten di mana penerbangan terendah ada pada Sabtu dan Minggu. Sementara Penerbangan berada di tingkat tertingginya untuk Senin di paruh pertama bulan, dan digantikan oleh hari Rabu di paruh kedua bulan.
Kita juga bisa mengulik lebih dalam dengan melihat dalam skala jam.
flights_dt %>%
mutate(minute = minute(dep_time)) %>%
group_by(minute) %>%
summarise(
avg_delay = mean(arr_delay, na.rm = TRUE),
n = n()) %>%
ggplot() + geom_line(aes(minute, avg_delay))
flights_try %>% group_by(week,wday) %>% summarise(jumlah = n()) %>%
ggplot() + geom_line(aes(week, jumlah, color = wday))
## `summarise()` has grouped output by 'week'. You can override using the `.groups` argument.
flights_dt%>%
mutate(dep_hour = update(dep_time, yday = 1))
## # A tibble: 328,063 x 10
## origin dest dep_delay arr_delay dep_time sched_dep_time
## <chr> <chr> <dbl> <dbl> <dttm> <dttm>
## 1 EWR IAH 2 11 2013-01-01 05:17:00 2013-01-01 05:15:00
## 2 LGA IAH 4 20 2013-01-01 05:33:00 2013-01-01 05:29:00
## 3 JFK MIA 2 33 2013-01-01 05:42:00 2013-01-01 05:40:00
## 4 JFK BQN -1 -18 2013-01-01 05:44:00 2013-01-01 05:45:00
## 5 LGA ATL -6 -25 2013-01-01 05:54:00 2013-01-01 06:00:00
## 6 EWR ORD -4 12 2013-01-01 05:54:00 2013-01-01 05:58:00
## 7 EWR FLL -5 19 2013-01-01 05:55:00 2013-01-01 06:00:00
## 8 LGA IAD -3 -14 2013-01-01 05:57:00 2013-01-01 06:00:00
## 9 JFK MCO -3 -8 2013-01-01 05:57:00 2013-01-01 06:00:00
## 10 LGA ORD -2 8 2013-01-01 05:58:00 2013-01-01 06:00:00
## # ... with 328,053 more rows, and 4 more variables: arr_time <dttm>,
## # sched_arr_time <dttm>, air_time <dbl>, dep_hour <dttm>
Exercise
flights_dt %>% mutate(day = yday(dep_time)) %>%
ggplot() + geom_freqpoly(aes(day), binwidth = 7)
Selanjutnya kita akan belajar tentang mengolah objek datetime menggunakan operasi aritmatika. Ada tiga kelas penting yang merepresentasikan time span.
Perlu kita tahu, bahwa saat kita mengurangi dua objek datetime, kita akan mendapat objek difftime.
h_age <- today() - ymd(19791014)
h_age
## Time difference of 15422 days
Lihat? hasil perbedaan antara dua objek datetime akan dimunculkan dalam bentuk hari. Objek difftime sendiri sebenarnya merekam rentang waktu dari detik, menit, jam, hari, atau minggu. Karena sifatnya yang ambigu, lubridate membaut tool alternatif sebesar ‘duration’.
Beberapa contoh :
as.duration(h_age)
## [1] "1332460800s (~42.22 years)"
Apa bedanya? duration akan menghasilkan objek baru yang berisi selisih waktu dengan satuan second. Di samppingnya, juga akan muncul konversi unit ke dalam tahun. Seluruh fungsi dan konstruktor dalam durasi adalah selisih atau difference waktu, dan dinyatakan dalam bentuk detik. Contoh saat kita menulis ddays(1); maka ini artinya, day 1- day 0 = 1 hari –> konversikan dari detik.
Selain ‘as.duration’, terdapat beberapa konstruktor lain dalam duration :
dyears(1) # Ini artinya selisih antara tahun 1 dengan tahun 0.
## [1] "31557600s (~1 years)"
dmonths(1) # ini artinya selisih antara bulan 1 dengan bulan 0
## [1] "2629800s (~4.35 weeks)"
dweeks(1) # Ini artinya durasi 1 minggu
## [1] "604800s (~1 weeks)"
ddays(1) # ini artinya durasi satu hari
## [1] "86400s (~1 days)"
dhours(1) # ini artinya durasi 1 jam
## [1] "3600s (~1 hours)"
dseconds(1) # ini artinya durasi satu detik
## [1] "1s"
# kelanjutannya sampai dmiliseconds dan dpiconds()
Operasi-operasi yng bisa dilakukan dengan datetime : * Penjumlahan dan perkalian waktu
2 * dyears(1)
## [1] "63115200s (~2 years)"
dyears(1) + dweeks(12) + dhours(15)
## [1] "38869200s (~1.23 years)"
Kita juga bisa melakukan operasi pengurangan
Period adalah fungsi datatime yng juga sama-sama mencari rentang waktu, namun period tidak mengeluarkan output dalam bentuk second secara otomatis, melainkan menggunakan unit waktu yang lebih umum.
seconds(15)
## [1] "15S"
minutes(10)
## [1] "10M 0S"
hours(c(12,24))
## [1] "12H 0M 0S" "24H 0M 0S"
Nah bisa kita lihat bahwa period akan mengikuti satuannya berdasarkan kontruktor yg ada. (sama seperti senjatanya)
Salah satu alat lain adalah interval. Ciri khusus interval adalah menampilkan secara eksplisit kondisi rentang waktu tersebut. Untuk membuat interval, ada 2 cara : * interval(starting point, end point) * starting_point%–%end point
next_year <- today() + years(1)
next_year
## [1] "2023-01-03"
(today() %--% next_year) / ddays(1)
## [1] 365
(today()%--% next_year) / days(1)
## [1] 365
(today()%--% ymd("2022-04-13")) / ddays(1)
## [1] 100
(ymd("2023-03-18")%--%today())/ddays(30)
## [1] -14.63333
today() %within% (ymd("2023-03-18")%--%today())
## [1] FALSE
#int_diff
z <- ymd("2022-01-04")
int_diff(c(z,z+100,z+1000))
## [1] 2022-01-04 UTC--2022-04-14 UTC 2022-04-14 UTC--2024-09-30 UTC
Coba pada flights data
Jika kita perhatikan pada data flights, kita akan menemukan adanya jam arr_time yang lebih kecil daripada dep_time. Kenapa bisa terjadi? hal ini karena penerbangan tersebut tiba di hari berikutnya atau penerbangan overnight. Karena akan sedikit membingungkan kita memperbaikinya dengan menambahkan satu hari pada arr_time juga scheduled_arr_time
flights_dt <- flights_dt %>% mutate(
overnight = arr_time < dep_time,
arr_time = arr_time + days(overnight * 1),
sched_arr_time = sched_arr_time + days(overnight * 1)
)
flights_dt %>% filter(overnight == TRUE)
## # A tibble: 10,633 x 10
## origin dest dep_delay arr_delay dep_time sched_dep_time
## <chr> <chr> <dbl> <dbl> <dttm> <dttm>
## 1 EWR BQN 9 -4 2013-01-01 19:29:00 2013-01-01 19:20:00
## 2 JFK DFW 59 NA 2013-01-01 19:39:00 2013-01-01 18:40:00
## 3 EWR TPA -2 9 2013-01-01 20:58:00 2013-01-01 21:00:00
## 4 EWR SJU -6 -12 2013-01-01 21:02:00 2013-01-01 21:08:00
## 5 EWR SFO 11 -14 2013-01-01 21:08:00 2013-01-01 20:57:00
## 6 LGA FLL -10 -2 2013-01-01 21:20:00 2013-01-01 21:30:00
## 7 EWR MCO 41 43 2013-01-01 21:21:00 2013-01-01 20:40:00
## 8 JFK LAX -7 -24 2013-01-01 21:28:00 2013-01-01 21:35:00
## 9 EWR FLL 49 28 2013-01-01 21:34:00 2013-01-01 20:45:00
## 10 EWR FLL -9 -14 2013-01-01 21:36:00 2013-01-01 21:45:00
## # ... with 10,623 more rows, and 4 more variables: arr_time <dttm>,
## # sched_arr_time <dttm>, air_time <dbl>, overnight <lgl>