“tibbles” adalah data frame, tetapi di tweak agar make life a little
easier. Kalau di buku ini bilang kenapa pakai tibble
instead yang lain, karena agar kita menggunakan library
tidyverse lebih mudah.
Semisal kalau kita sudah punya data terus ingin kita convert jadi
tibble cukup gunakan as_tibble()
as_tibble(iris)
## # A tibble: 150 × 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # ℹ 140 more rows
Atau semisal kalau ingin membuatnya dari scratch, kita bisa
menggunakan tibble()
tibble(
x = 1:5,
y = 1,
z = x ^ 2 + y
)
## # A tibble: 5 × 3
## x y z
## <int> <dbl> <dbl>
## 1 1 1 2
## 2 2 1 5
## 3 3 1 10
## 4 4 1 17
## 5 5 1 26
Lalu menariknya adalah perbedaan dari data.frame()
daripada tibble() adalah tibble tidak pernah mengubah tipe
data dari input (e.g. tidak pernah converts string menjadi factors),
tidak pernah mengganti nama variables nya, dan tidak pernah membuat row
names (?)
Lalu pada tibble kita bisa membuat nama columns dengan nama yang nyeleneh atau non-syntatic names
tb <- tibble(
`:)` = "smile",
` ` = "space",
`2000` = "number"
)
tb
## # A tibble: 1 × 3
## `:)` ` ` `2000`
## <chr> <chr> <chr>
## 1 smile space number
Lalu ada juga yang namanya tribble() yaitu
transposed tibble merupakan customised untuk data
entry. ex:
tribble(
~x, ~y, ~z,
#--|--|----
"a", 2, 3.6,
"b", 1, 8.5
)
## # A tibble: 2 × 3
## x y z
## <chr> <dbl> <dbl>
## 1 a 2 3.6
## 2 b 1 8.5
Ada dua perbedaan antara tibble vs data.frame yaitu:
printing dan subsetting
Kalau pake tibble hanya mengeluarkan output 10 rows pertama dan menampilkan seluruh columns yang fit on screen. Yang dimana ini berguna ketika kita memiliki data yang besar.
tibble(
a = lubridate::now() + runif(1e3) * 86400,
b = lubridate::today() + runif(1e3) * 30,
c = 1:1e3,
d = runif(1e3),
e = sample(letters, 1e3, replace = TRUE)
)
## # A tibble: 1,000 × 5
## a b c d e
## <dttm> <date> <int> <dbl> <chr>
## 1 2023-05-02 05:04:29 2023-05-05 1 0.0295 g
## 2 2023-05-02 12:30:32 2023-05-23 2 0.901 k
## 3 2023-05-02 09:17:19 2023-05-16 3 0.0859 k
## 4 2023-05-01 20:22:51 2023-05-05 4 0.123 e
## 5 2023-05-02 15:05:13 2023-05-26 5 0.641 s
## 6 2023-05-02 02:31:41 2023-05-10 6 0.974 g
## 7 2023-05-01 22:36:03 2023-05-29 7 0.562 q
## 8 2023-05-02 14:18:56 2023-05-17 8 0.328 g
## 9 2023-05-02 04:53:03 2023-05-07 9 0.572 i
## 10 2023-05-02 18:07:59 2023-05-12 10 0.571 t
## # ℹ 990 more rows
Alasan kenapa tibbles dibuat adalah agar kita tidak overwhelm dengan output di console ketika kita print data frames yang besar!!!
Sebenernya kita bisa mainkan parameter pada tibble untuk nge output jumlah baris dan kolom nya berapa
Atau, kita bisa menggunakan function View()
nycflights13::flights %>%
View()
Jika kita ingin extract data / value dari single variable atau
column, kita bisa menggunakan $ dan [[.
Perbedaannya [[ bisa extract by name atau position
sedangkan $ hanya bisa extract by name. Contoh:
df <- tibble(
x = runif(5),
y = rnorm(5)
)
# Extract by name using dollar sign
df$x
## [1] 0.4689837 0.3907106 0.6622299 0.3303831 0.5590671
# Extract by name using bracket kotak
df[["x"]]
## [1] 0.4689837 0.3907106 0.6622299 0.3303831 0.5590671
# Extract by position
df[[1]]
## [1] 0.4689837 0.3907106 0.6622299 0.3303831 0.5590671
Kita juga bisa menggunakan pipe ketika extract data, cukup
menggunakan special placeholder .
df %>% .$x
## [1] 0.4689837 0.3907106 0.6622299 0.3303831 0.5590671
df %>% .[["x"]]
## [1] 0.4689837 0.3907106 0.6622299 0.3303831 0.5590671
Untuk melakukan read data, kita bisa menggunakan library
readr yang merupakan core dari library
tidyverse.
Function read data yang paling sering digunakan di R adalah:
read_csv() –> comma delimited files
read_csv2() –> semicolon separated files
read_tsv() –> tab delimited files
read_delim() –> files with any delimiter
read_fwf() –> fixed with files
read_log() –> read Apache style log
files
heights <- read_csv(<PATH_TO_FILE>)
Kita juga bisa langsung menggunakan read_csv() untuk
inline csv file
read_csv("a,b,c
1,2,3
4,5,6")
## Rows: 2 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (3): a, b, c
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## # A tibble: 2 × 3
## a b c
## <dbl> <dbl> <dbl>
## 1 1 2 3
## 2 4 5 6
Selain itu, jika kita memiliki data yang tidak memiliki columns name
kita bisa langsung pass cols name nya di read_csv()
read_csv("1,2,3\n4,5,6", col_names = c("x", "y", "z"))
## Rows: 2 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (3): x, y, z
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## # A tibble: 2 × 3
## x y z
## <dbl> <dbl> <dbl>
## 1 1 2 3
## 2 4 5 6
Tujuan menggunakan parser adalah untuk kita convert data atau deal with different data types of input ke dalam bentuk yang kita inginkan. Parser yang sering digunakan di R:
parse_logical()
parse_integer()
parse_double() –> strict numeric
parse_double("1.23")
## [1] 1.23
parse_double("1,23", locale = locale(decimal_mark = ","))
## [1] 1.23
parse_number() –> flexible numericparse_number("$100")
## [1] 100
parse_number("20%")
## [1] 20
parse_number("It cost $123.45")
## [1] 123.45
parse_character() –> character encoding
parse_factor() –> create factor
parse_datetime() –> using ISO8601
parse_datetime("2010-10-01T2010")
## [1] "2010-10-01 20:10:00 UTC"
# If time is omitted, it will be set to midnight
parse_datetime("20101010")
## [1] "2010-10-10 UTC"
parse_date()parse_date("2010-10-01")
## [1] "2010-10-01"
parse_time()library(hms)
##
## Attaching package: 'hms'
## The following object is masked from 'package:lubridate':
##
## hms
parse_time("01:10 am")
## 01:10:00
parse_time("20:10:01")
## 20:10:01
Untuk save data yang setelah kita olah, kita bisa simpan dalam bentuk
.csv atau .tsv. Kita bisa menggunakan function
write_csv()
write_csv(<NAMA_VAR_DATA>, <OUTPUT_NAME_FILE.csv>)
Selain data yang sudah disebutkan di section atas, sebenarnya masih banyak data yang bisa digunakan di R, contohnya:
haven untuk membaca SPSS, Stata, dan SAS
readxl untuk membaca file excel
DBI untuk membaca database seperti RMySQL, RSQLite, RPostreSQL, dll
jsonlite
xml2
Tidy data adalah sebuah proses membuat data kita menjadi bentuk yang konsisten dan lebih terorganisir. Tetapi proses ini itu membutuhkan effort.
Jika ingin membaca lebih detail tentang underlying theory dari Tidy Data bisa baca di link berikut
Terdapat “rules” untuk membuat dataset tidy:
Each variables must have its own column
Each observation must have its own row
Each value must have its own cell
Nanti kasih github nya
Multiple tables of data itu disebut dengan relational data. Bentuk umum dari relational data adalah RDBMS.
Tentu karena kita membahas tentang Relational data, maka akan ada komponen Keys. Bentuk dari keys adalah:
Primary key
Foreign key
Join merupakan komponen yang penting dari relational data, karena kita bisa melakukan combine data dengan antar tabel. Join yang dipakai di R adalah:
Left Join
Right Join
Inner Join
Full Join
Pada chapter ini akan belajar tentang basics string bekerja, bagaimana cara membuatnya, dan string manipulation.
Untuk cara membuat string cukup simple, kita bisa menggunakan single
quotes ' atau double quotes "
string1 <- "This is a string"
string2 <- 'If I want to include a "quote" inside a string, I use single quotes'
Untuk mengecek panjang dari sebuah strings, kita bisa menggunakan
str_length()
str_length(c("a", "R for data science", NA))
## [1] 1 18 NA
Untuk combine dua atau lebih strings, bisa menggunakan
str_c()
str_c("R", "for", "Data", "Science", sep = " ")
## [1] "R for Data Science"
Kita juga bisa melakukan extract which parts of string menggunakan
str_sub()
x <- c("Apple", "Banana", "Pear")
str_sub(x, 1, 3)
## [1] "App" "Ban" "Pea"
# negative numbers count backwards from end
str_sub(x, -3, -1)
## [1] "ple" "ana" "ear"
Terus pada buku ini pada string nya, mainly akan bahas tentang regex manipulation. Tapi itu takes time, jadi di skip terlebih dahulu.
Factors digunakan untuk categorical variables, yang dimana nilai nya udah fixed dan known set of possible values. Biasanya akan kepakai ketika kita akan membuat data Survey.
Data yang yang categorical (nominal) dan ordered categorical (ordinal). Sehingga kita bisa melakukan ordering
Semisal kita mau membuat variable untuk menyimpan month
x1 <- c("Dec", "Apr", "Jan", "Mar")
Tetapi tidak bisa kita sort data nya sesuai dengan keinginan kita
sort(x1)
## [1] "Apr" "Dec" "Jan" "Mar"
Maka, kita bisa fix problem tersebut menggunakan factor. Untuk membuat factor, kita bisa mengguakan list of the valid levels:
month_levels <- c(
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
)
Lalu, kita tinggal membuat factor
y1 <- factor(x1, levels = month_levels)
sort(y1)
## [1] Jan Mar Apr Dec
## Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
Terdapat tiga tipe date/time:
date. Tibble akan print sebagai
<date>
time within a day. Tibbel akan print sebagai
<time>
date-time merupakan date plus a time. Tibble
akan print sebagai <dttm>
Kita bisa dapetin current date or date-time menggunakan
today() atau now()
today()
## [1] "2023-05-01"
now()
## [1] "2023-05-01 19:15:35 WIB"
Kita juga bisa membuat date/time dengan cara:
From a string
From individual date-time components
From an existing date/time object
Kita tinggal arange “y”, “m”, dan “d” sesuai dengan order yang kita inginkan
ymd("2017-01-31")
## [1] "2017-01-31"
mdy("January 31st, 2017")
## [1] "2017-01-31"
dmy("31-Jan-2017")
## [1] "2017-01-31"
ymd(20170131)
## [1] "2017-01-31"
Selain menggunakan date, kita juga bisa menggunakan date-time. Untuk
parsing nya kita tinggal tambahkan “h”, “m”, “s”. Untuk default nya akan
ter-parsing ke dalam bentuk UTC
ymd_hms("2017-01-31 20:11:59")
## [1] "2017-01-31 20:11:59 UTC"
mdy_hm("01/31/2017 08:01")
## [1] "2017-01-31 08:01:00 UTC"
Kita juga bisa membuat date-time dari data yang terdapat dari
multiple columns. Contoh kita akan menggunakan data flights
dan kita bisa menggunakan make_date() untuk membuat date
dan make_datetime() untuk membuat date-times
flights %>%
select(year, month, day, hour, minute) %>%
mutate(departure = make_datetime(year, month, day, hour, minute))
## # A tibble: 336,776 × 6
## year month day hour minute departure
## <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
## # ℹ 336,766 more rows
Untuk next nya kita akan menggunakan data berikut
# function create datetime
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 × 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
## # ℹ 328,053 more rows
## # ℹ 3 more variables: arr_time <dttm>, sched_arr_time <dttm>, air_time <dbl>
Enaknya menggunakan data datetime kita bisa melakukan visualisasi
flights_dt %>%
ggplot(aes(dep_time)) +
geom_freqpoly(binwidth = 86400) # 86400 seconds = 1 day
Kita juga bisa mengambil data per day nya
flights_dt %>%
filter(dep_time < ymd(20130102)) %>%
ggplot(aes(dep_time)) +
geom_freqpoly(binwidth = 600) # 600 s = 10 minutes
Kita juga bisa melakukan switch antara date-time dan date, bisa
mengguanakan as_datetime() dan as_date()
as_datetime(today())
## [1] "2023-05-01 UTC"
as_date(now())
## [1] "2023-05-01"
Kita bisa mengambil individual komponen menggunakan
year(), month(), mday() (day of
the month), yday() (day of the year), wday()
(day of the week), hour(), minute(), dan
second()
Semisal kita ingin mengambil flights depart during the week
flights_dt %>%
mutate(wday = wday(dep_time, label = TRUE)) %>%
ggplot(aes(x = wday)) +
geom_bar()
Ternyata kita bisa menemukan pattern yang menarik jika kita melihat average departure delay by minute with the hours. Ternyata flights yang terbang di minutes 20-30 dan 50-60 memiliki nilai lower delays daripada yang lain!!!
flights_dt %>%
mutate(minute = minute(dep_time)) %>%
group_by(minute) %>%
summarise(
avg_delay = mean(arr_delay, na.rm = TRUE),
n = n()) %>%
ggplot(aes(minute, avg_delay)) +
geom_line()
Pada datetime kita juga bisa menggunakan rounding ke nearby unit of
time, function nya floor_date(), round_date(),
dan ceiling_date(). Kalau round down pakai “floor”,
sedangkan round up pakai “ceiling”.
Kita juga bisa melakukan arithmetic pada dates, mulai dari subtraction, addition, dan division. Kita bisa menggunakan tiga komponen/classes yang merepresentasikan time spans:
durations, represent an exact number of seconds
periods, represent human units like weeks and months
intervals, represent a starting and ending point
Ex:
# How old is Hadley?
h_age <- today() - ymd(19791014)
h_age
## Time difference of 15905 days