Manajemen Data dengan Tidyverse

Cara Praktik

Silakan siapkan aplikasi RStudio di perangkat masing-masing, lalu buatlah file RMarkdown baru dan salin bagian kodenya saja untuk ditempelkan ke dalam setiap chunk RMarkdown; selanjutnya, jalankan kode secara bertahap baris demi baris menggunakan shortcut Ctrl + Enter atau tombol run current chunk agar alur kerjanya lebih mudah dipahami dan outputnya sesuai.

Tidyverse

Tidyverse adalah kumpulan package R yang berfungsi untuk melakukan pengolahan data seperti import, subset, visualisasi, transformasi, dan lain sebagainya. Tidyverse diciptakan oleh Hadley Wickham dan timnya dengan tujuan menyediakan semua tools untuk membersihkan, merapikan dan bekerja dengan data.

Terdapat ggplot2 untuk visualisasi data, yang memungkinkan pengguna membuat grafik yang kompleks dengan sintaks yang elegan. dplyr digunakan untuk data wrangling, yaitu manipulasi data seperti filter, sort, dan agregasi. read membantu dalam reading data dari berbagai format seperti CSV dengan cara yang cepat dan efisien. tibble menawarkan modern data frames, struktur data yang lebih baik dari data.frame tradisional di R.

Di bagian bawah, lubridate mempermudah pengguna dalam working with dates, seperti parsing dan manipulasi tanggal/waktu. forcats mendukung dealing with factors, yaitu pengelolaan data kategorik di R. tidyr berperan penting dalam data tidying, membantu merapikan data agar sesuai dengan prinsip tidy data. purrr mempermudah iterasi dan manipulasi list atau vektor secara rapi dan konsisten, menggantikan kebutuhan looping (perulangan) tradisional.

Install Tidyverse

Silakan perhatikan blok kode di bawah; baris #install.packages(“tidyverse”) diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan Tidyverse ini untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library(tidyverse) untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("tidyverse")
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Package dalam tidyverse

tidyverse_packages()
##  [1] "broom"         "conflicted"    "cli"           "dbplyr"       
##  [5] "dplyr"         "dtplyr"        "forcats"       "ggplot2"      
##  [9] "googledrive"   "googlesheets4" "haven"         "hms"          
## [13] "httr"          "jsonlite"      "lubridate"     "magrittr"     
## [17] "modelr"        "pillar"        "purrr"         "ragg"         
## [21] "readr"         "readxl"        "reprex"        "rlang"        
## [25] "rstudioapi"    "rvest"         "stringr"       "tibble"       
## [29] "tidyr"         "xml2"          "tidyverse"

Tibble

Tibble adalah format tabel data modern di R yang merupakan bagian dari ekosistem tidyverse. Tibble dirancang untuk memperbaiki kekurangan data.frame (format tabel bawaan R) agar proses analisis data menjadi lebih stabil dan minim kesalahan. Pada dasarnya Tibble masih merupakan dataframe, hanya saja tampilan print/outputnya lebih baik dibandingkan dataframe biasa.

Membuat tibble

Nama kolom tibble bisa memuat spasi

tibble_karyawan <- tibble(
  `nama karyawan` = c("Andi", "Budi", "Cici"),
  gaji = c(5000000, 6000000, 5500000),
  tunjangan = list(c(100, 200), 150, c(150, 250, 50))
)
tibble_karyawan
## # A tibble: 3 × 3
##   `nama karyawan`    gaji tunjangan
##   <chr>             <dbl> <list>   
## 1 Andi            5000000 <dbl [2]>
## 2 Budi            6000000 <dbl [1]>
## 3 Cici            5500000 <dbl [3]>

Memanggil isi tibble

Cici memiliki 3 nilai tunjangan

tibble_karyawan$tunjangan[[3]]
## [1] 150 250  50

Data Flights dengan tibble

Silakan perhatikan blok kode di bawah; baris #install.packages diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("nycflights13")
library(nycflights13)
flights
## # A tibble: 336,776 × 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
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 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>

Merubah tibble menjadi dataframe

df_flights <- as.data.frame(flights)
# menampilkan data teratas
head(df_flights)
##   year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## 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
##   arr_delay carrier flight tailnum origin dest air_time distance hour minute
## 1        11      UA   1545  N14228    EWR  IAH      227     1400    5     15
## 2        20      UA   1714  N24211    LGA  IAH      227     1416    5     29
## 3        33      AA   1141  N619AA    JFK  MIA      160     1089    5     40
## 4       -18      B6    725  N804JB    JFK  BQN      183     1576    5     45
## 5       -25      DL    461  N668DN    LGA  ATL      116      762    6      0
## 6        12      UA   1696  N39463    EWR  ORD      150      719    5     58
##             time_hour
## 1 2013-01-01 05:00:00
## 2 2013-01-01 05:00:00
## 3 2013-01-01 05:00:00
## 4 2013-01-01 05:00:00
## 5 2013-01-01 06:00:00
## 6 2013-01-01 05:00:00

Memanggil nama kolom data frame bisa parsial

Ini tidak berlaku untuk tibble, nama kolom harus dipanggil lengkap.

head(df_flights$y)
## [1] 2013 2013 2013 2013 2013 2013

Merubah dataframe menjadi tibble

df_people <- data.frame(
  id       = c(1, 2, 3, 4, 5),
  name     = c("Adam", "Eva", "Miki", "Yola", "Jack"), 
  age      = c(46, 48, 21, 19, 17), 
  gender   = c("male", rep("female", 3), "male"), 
  drives   = c(TRUE, TRUE, FALSE, TRUE, FALSE) 
)
tibble_people <- as_tibble(df_people)
tibble_people
## # A tibble: 5 × 5
##      id name    age gender drives
##   <dbl> <chr> <dbl> <chr>  <lgl> 
## 1     1 Adam     46 male   TRUE  
## 2     2 Eva      48 female TRUE  
## 3     3 Miki     21 female FALSE 
## 4     4 Yola     19 female TRUE  
## 5     5 Jack     17 male   FALSE

Melihat summary

summary(tibble_people)
##        id        name                age          gender         
##  Min.   :1   Length:5           Min.   :17.0   Length:5          
##  1st Qu.:2   Class :character   1st Qu.:19.0   Class :character  
##  Median :3   Mode  :character   Median :21.0   Mode  :character  
##  Mean   :3                      Mean   :30.2                     
##  3rd Qu.:4                      3rd Qu.:46.0                     
##  Max.   :5                      Max.   :48.0                     
##    drives       
##  Mode :logical  
##  FALSE:2        
##  TRUE :3        
##                 
##                 
## 

Melihat tipe variabel untuk tibble

glimpse(tibble_people)
## Rows: 5
## Columns: 5
## $ id     <dbl> 1, 2, 3, 4, 5
## $ name   <chr> "Adam", "Eva", "Miki", "Yola", "Jack"
## $ age    <dbl> 46, 48, 21, 19, 17
## $ gender <chr> "male", "female", "female", "female", "male"
## $ drives <lgl> TRUE, TRUE, FALSE, TRUE, FALSE

Merubah tipe variabel gender menjadi factor

tibble_people$gender <- factor(tibble_people$gender)
summary(tibble_people)
##        id        name                age          gender    drives       
##  Min.   :1   Length:5           Min.   :17.0   female:3   Mode :logical  
##  1st Qu.:2   Class :character   1st Qu.:19.0   male  :2   FALSE:2        
##  Median :3   Mode  :character   Median :21.0              TRUE :3        
##  Mean   :3                      Mean   :30.2                             
##  3rd Qu.:4                      3rd Qu.:46.0                             
##  Max.   :5                      Max.   :48.0

Memanggil kolom pada tibble

Jika memanggil kolom menggunakan urutan, hasilnya berupa tibble

tibble_people[ ,2]
## # A tibble: 5 × 1
##   name 
##   <chr>
## 1 Adam 
## 2 Eva  
## 3 Miki 
## 4 Yola 
## 5 Jack

Menyaring baris pada tibble

Umur dibawah 30

tibble_people[tibble_people$age < 30, ]
## # A tibble: 3 × 5
##      id name    age gender drives
##   <dbl> <chr> <dbl> <fct>  <lgl> 
## 1     3 Miki     21 female FALSE 
## 2     4 Yola     19 female TRUE  
## 3     5 Jack     17 male   FALSE

`

Readr

readr adalah suatu package yang digunakan untuk import data seperti csv, txt, dan lain sebagainya. Package ini dinilai mampu membaca data lebih cepat dibandingkan read.csv, read.table dan sejenisnya. Data hasil import dari readr berbentuk tibble.

Persiapkan File Data

Sebelum memulai readr, silahkan mengunduh data sesuai folder melalui tautan berikut klik disini. Setelah berhasil diunduh, simpan file tersebut ke dalam direktori penyimpanan lokal Anda (contoh didalam folder dengan alamat: D:/Download D/Data) agar mudah diakses saat praktikum.

Memanggil Data

# memanggil data csv dengan separator koma (,)
penjualankoma<-read_csv("D:/Download D/Data/penjualan.csv")
penjualankoma
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000
# memanggil data csv dengan separator titik koma (;)
penjualantitikoma <- read_csv2("D:/Download D/Data/penjualan2.csv")
## ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
## Rows: 5 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (3): ID, Nama, Gender
## dbl (2): Usia, Penjualan
## 
## ℹ 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.
penjualantitikoma
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000
# memanggil data txt dengan separator tab
penjualantxtab <- read_tsv("D:/Download D/Data/penjualan.txt")
## Rows: 5 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (3): ID, Nama, Gender
## dbl (1): Usia
## num (1): Penjualan
## 
## ℹ 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.
penjualantxtab
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000
# memanggil data txt dengan separator (|)
penjualantxtsep <- read_delim("D:/Download D/Data/penjualan2.txt", delim='|')
## Rows: 5 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: "|"
## chr (3): ID, Nama, Gender
## dbl (2): Usia, Penjualan
## 
## ℹ 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.
penjualantxtsep
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000
# read_delim secara umum dapat memanggil file dengan berbagai macam separator
# memanggil data csv dengan separator (,)
penjualanreadelimkoma <- read_delim("D:/Download D/Data/penjualan.csv", delim=',')
## Rows: 5 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): ID, Nama, Gender
## dbl (1): Usia
## num (1): Penjualan
## 
## ℹ 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.
penjualanreadelimkoma
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000
# memanggil data txt dengan separator tab (\t)
penjualanreadelimtab <- read_delim("D:/Download D/Data/penjualan.txt", delim='\t')
## Rows: 5 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (3): ID, Nama, Gender
## dbl (1): Usia
## num (1): Penjualan
## 
## ℹ 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.
penjualanreadelimtab
## # A tibble: 5 × 5
##   ID    Nama     Usia Gender    Penjualan
##   <chr> <chr>   <dbl> <chr>         <dbl>
## 1 321A  Eiden      35 Laki-laki   1125600
## 2 44B   Olivia     28 Perempuan    987000
## 3 984C  Brandon    25 Laki-laki   2134000
## 4 653D  Wendy      30 Perempuan    756000
## 5 178E  Loki       26 Laki-laki   1698000

Menyimpan data

Fungsi-fungsi (write_csv, write_csv2, write_delim, dan write_tsv) berasal dari package readr. Setelah run kode ini maka file akan tersimpan di folder D:/Download D/Data/

# Definisikan alamat folder tujuan menyimpan agar tidak mengetik ulang, misalkan saya ada folder
path_tujuan <- "D:/Download D/Data/"

# mengeksport tibble ke csv dengan separator koma
write_csv(tibble_karyawan, paste0(path_tujuan, 'tibble_karyawancobakoma.csv'))

# mengeksport tibble ke csv dengan separator titik koma
write_csv2(tibble_karyawan, paste0(path_tujuan, 'tibble_karyawancobatitikkoma.csv'))

# mengeksport tibble ke txt dengan separator spasi
write_delim(tibble_karyawan, paste0(path_tujuan, 'tibble_karyawancobaspasi.txt'), delim=' ')

# mengeksport tibble ke txt dengan separator tab
write_tsv(tibble_karyawan, paste0(path_tujuan, 'tibble_karyawancobatab.txt'))

Dplyr

Silakan perhatikan blok kode di bawah; baris #install.packages(“tidyverse”) diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan Tidyverse ini untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library(tidyverse) untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("tidyverse")
library(tidyverse)

dplyr adalah suatu package yang digunakan untuk data wrangling seperti transformasi dataframe, melakukan aggregate, menampilkan statistika deskriptif, menggabungkan dataframe, mengubah kolom dan baris, mengurutkan data, dan lain sebagainya

Persiapkan File Data

Sebelum memulai dplyr, silahkan melihat data melalui tautan berikut klik disini. Ingat data di sini format CSV. Kita mengambil data dari penyedia yang ada di Github.

# Menyimpan URL raw data GitHub ke dalam variabel
url <- "https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-09-01/key_crop_yields.csv"

# Membaca data read_csv
df_crop <- read_csv(url)
## Rows: 13075 Columns: 14
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (2): Entity, Code
## dbl (12): Year, Wheat (tonnes per hectare), Rice (tonnes per hectare), Maize...
## 
## ℹ 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.
# Melihat data
glimpse(df_crop)
## Rows: 13,075
## Columns: 14
## $ Entity                             <chr> "Afghanistan", "Afghanistan", "Afgh…
## $ Code                               <chr> "AFG", "AFG", "AFG", "AFG", "AFG", …
## $ Year                               <dbl> 1961, 1962, 1963, 1964, 1965, 1966,…
## $ `Wheat (tonnes per hectare)`       <dbl> 1.0220, 0.9735, 0.8317, 0.9510, 0.9…
## $ `Rice (tonnes per hectare)`        <dbl> 1.5190, 1.5190, 1.5190, 1.7273, 1.7…
## $ `Maize (tonnes per hectare)`       <dbl> 1.4000, 1.4000, 1.4260, 1.4257, 1.4…
## $ `Soybeans (tonnes per hectare)`    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Potatoes (tonnes per hectare)`    <dbl> 8.6667, 7.6667, 8.1333, 8.6000, 8.8…
## $ `Beans (tonnes per hectare)`       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Peas (tonnes per hectare)`        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Cassava (tonnes per hectare)`     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Barley (tonnes per hectare)`      <dbl> 1.0800, 1.0800, 1.0800, 1.0857, 1.0…
## $ `Cocoa beans (tonnes per hectare)` <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Bananas (tonnes per hectare)`     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…

Mengubah semua kolom berkarakter (character) menjadi factor

df_crop$Entity <- as.factor(df_crop$Entity)
df_crop$Code <- as.factor(df_crop$Code)
#Periksa apakah ada perubahan
glimpse(df_crop)
## Rows: 13,075
## Columns: 14
## $ Entity                             <fct> "Afghanistan", "Afghanistan", "Afgh…
## $ Code                               <fct> AFG, AFG, AFG, AFG, AFG, AFG, AFG, …
## $ Year                               <dbl> 1961, 1962, 1963, 1964, 1965, 1966,…
## $ `Wheat (tonnes per hectare)`       <dbl> 1.0220, 0.9735, 0.8317, 0.9510, 0.9…
## $ `Rice (tonnes per hectare)`        <dbl> 1.5190, 1.5190, 1.5190, 1.7273, 1.7…
## $ `Maize (tonnes per hectare)`       <dbl> 1.4000, 1.4000, 1.4260, 1.4257, 1.4…
## $ `Soybeans (tonnes per hectare)`    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Potatoes (tonnes per hectare)`    <dbl> 8.6667, 7.6667, 8.1333, 8.6000, 8.8…
## $ `Beans (tonnes per hectare)`       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Peas (tonnes per hectare)`        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Cassava (tonnes per hectare)`     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Barley (tonnes per hectare)`      <dbl> 1.0800, 1.0800, 1.0800, 1.0857, 1.0…
## $ `Cocoa beans (tonnes per hectare)` <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ `Bananas (tonnes per hectare)`     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA,…

Select

Select adalah fungsi yang digunakan untuk memilih kolom dari suatu dataframe.

data_select <- select(df_crop, Entity, Year, `Wheat (tonnes per hectare)`)
data_select
## # A tibble: 13,075 × 3
##    Entity       Year `Wheat (tonnes per hectare)`
##    <fct>       <dbl>                        <dbl>
##  1 Afghanistan  1961                        1.02 
##  2 Afghanistan  1962                        0.974
##  3 Afghanistan  1963                        0.832
##  4 Afghanistan  1964                        0.951
##  5 Afghanistan  1965                        0.972
##  6 Afghanistan  1966                        0.867
##  7 Afghanistan  1967                        1.12 
##  8 Afghanistan  1968                        1.16 
##  9 Afghanistan  1969                        1.19 
## 10 Afghanistan  1970                        0.956
## # ℹ 13,065 more rows

Memilih beberapa kolom pertama

select(df_crop, 1:4)
## # A tibble: 13,075 × 4
##    Entity      Code   Year `Wheat (tonnes per hectare)`
##    <fct>       <fct> <dbl>                        <dbl>
##  1 Afghanistan AFG    1961                        1.02 
##  2 Afghanistan AFG    1962                        0.974
##  3 Afghanistan AFG    1963                        0.832
##  4 Afghanistan AFG    1964                        0.951
##  5 Afghanistan AFG    1965                        0.972
##  6 Afghanistan AFG    1966                        0.867
##  7 Afghanistan AFG    1967                        1.12 
##  8 Afghanistan AFG    1968                        1.16 
##  9 Afghanistan AFG    1969                        1.19 
## 10 Afghanistan AFG    1970                        0.956
## # ℹ 13,065 more rows

Mengecualikan kolom

select(df_crop, -c(`Entity`, `Year`))
## # A tibble: 13,075 × 12
##    Code  Wheat (tonnes per hecta…¹ Rice (tonnes per hec…² Maize (tonnes per he…³
##    <fct>                     <dbl>                  <dbl>                  <dbl>
##  1 AFG                       1.02                    1.52                   1.4 
##  2 AFG                       0.974                   1.52                   1.4 
##  3 AFG                       0.832                   1.52                   1.43
##  4 AFG                       0.951                   1.73                   1.43
##  5 AFG                       0.972                   1.73                   1.44
##  6 AFG                       0.867                   1.52                   1.44
##  7 AFG                       1.12                    1.92                   1.41
##  8 AFG                       1.16                    1.95                   1.71
##  9 AFG                       1.19                    1.98                   1.72
## 10 AFG                       0.956                   1.81                   1.48
## # ℹ 13,065 more rows
## # ℹ abbreviated names: ¹​`Wheat (tonnes per hectare)`,
## #   ²​`Rice (tonnes per hectare)`, ³​`Maize (tonnes per hectare)`
## # ℹ 8 more variables: `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>, …

Memilih kolom yang mengandung teks

select(df_crop, contains("(tonnes per hectare)"))
## # A tibble: 13,075 × 11
##    `Wheat (tonnes per hectare)` Rice (tonnes per hectar…¹ Maize (tonnes per he…²
##                           <dbl>                     <dbl>                  <dbl>
##  1                        1.02                       1.52                   1.4 
##  2                        0.974                      1.52                   1.4 
##  3                        0.832                      1.52                   1.43
##  4                        0.951                      1.73                   1.43
##  5                        0.972                      1.73                   1.44
##  6                        0.867                      1.52                   1.44
##  7                        1.12                       1.92                   1.41
##  8                        1.16                       1.95                   1.71
##  9                        1.19                       1.98                   1.72
## 10                        0.956                      1.81                   1.48
## # ℹ 13,065 more rows
## # ℹ abbreviated names: ¹​`Rice (tonnes per hectare)`,
## #   ²​`Maize (tonnes per hectare)`
## # ℹ 8 more variables: `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>, …

Operator Pipe %>%

Operator Pipe adalah fitur yang memungkinkan mengalirkan data atau hasil dari satu fungsi secara langsung ke fungsi berikutnya. Pipe secara bahasa sebagai padanan kata “dan kemudian” dalam alur logika kode.

#tidak perlu lagi menyebut nama data di dalam select
#data df_crop dan kemudian dipilih 1-3 kolom pertama dan kemudian dipilih yang bertipe numerik 
df_crop %>% select(1:3) %>% select(where(is.numeric)) 
## # A tibble: 13,075 × 1
##     Year
##    <dbl>
##  1  1961
##  2  1962
##  3  1963
##  4  1964
##  5  1965
##  6  1966
##  7  1967
##  8  1968
##  9  1969
## 10  1970
## # ℹ 13,065 more rows

Filter

filter adalah fungsi yang digunakan untuk memilih baris sesuai dengan kriteria tertentu.

#data_filter berisi data yang telah disaring untuk Entity dari Indonesia
data_filter<-filter(df_crop, Entity=="Indonesia")
data_filter
## # A tibble: 58 × 14
##    Entity    Code   Year `Wheat (tonnes per hectare)` Rice (tonnes per hectare…¹
##    <fct>     <fct> <dbl>                        <dbl>                      <dbl>
##  1 Indonesia IDN    1961                           NA                       1.76
##  2 Indonesia IDN    1962                           NA                       1.79
##  3 Indonesia IDN    1963                           NA                       1.72
##  4 Indonesia IDN    1964                           NA                       1.76
##  5 Indonesia IDN    1965                           NA                       1.77
##  6 Indonesia IDN    1966                           NA                       1.77
##  7 Indonesia IDN    1967                           NA                       1.76
##  8 Indonesia IDN    1968                           NA                       2.14
##  9 Indonesia IDN    1969                           NA                       2.25
## 10 Indonesia IDN    1970                           NA                       2.38
## # ℹ 48 more rows
## # ℹ abbreviated name: ¹​`Rice (tonnes per hectare)`
## # ℹ 9 more variables: `Maize (tonnes per hectare)` <dbl>,
## #   `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>, …

Menyaring suatu kolom tanpa nilai NA

filter(df_crop, !is.na(`Wheat (tonnes per hectare)`))
## # A tibble: 8,101 × 14
##    Entity      Code   Year `Wheat (tonnes per hectare)` Rice (tonnes per hecta…¹
##    <fct>       <fct> <dbl>                        <dbl>                    <dbl>
##  1 Afghanistan AFG    1961                        1.02                      1.52
##  2 Afghanistan AFG    1962                        0.974                     1.52
##  3 Afghanistan AFG    1963                        0.832                     1.52
##  4 Afghanistan AFG    1964                        0.951                     1.73
##  5 Afghanistan AFG    1965                        0.972                     1.73
##  6 Afghanistan AFG    1966                        0.867                     1.52
##  7 Afghanistan AFG    1967                        1.12                      1.92
##  8 Afghanistan AFG    1968                        1.16                      1.95
##  9 Afghanistan AFG    1969                        1.19                      1.98
## 10 Afghanistan AFG    1970                        0.956                     1.81
## # ℹ 8,091 more rows
## # ℹ abbreviated name: ¹​`Rice (tonnes per hectare)`
## # ℹ 9 more variables: `Maize (tonnes per hectare)` <dbl>,
## #   `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>, …

Menyaring lebih dari satu kondisi

filter(df_crop,Code=="IDN" , Year > 2000, `Bananas (tonnes per hectare)` <50 )
## # A tibble: 1 × 14
##   Entity    Code   Year `Wheat (tonnes per hectare)` `Rice (tonnes per hectare)`
##   <fct>     <fct> <dbl>                        <dbl>                       <dbl>
## 1 Indonesia IDN    2003                           NA                        4.54
## # ℹ 9 more variables: `Maize (tonnes per hectare)` <dbl>,
## #   `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>,
## #   `Cocoa beans (tonnes per hectare)` <dbl>,
## #   `Bananas (tonnes per hectare)` <dbl>

Arrange

arrange adalah fungsi yang digunakan untuk mengurutkan data. Gunakan desc untuk mengurutkan secara menurun.

#mengurutkan data berdasarkan Year secara menaik dan annual salary menurun 
arrange(df_crop, Year, desc(`Rice (tonnes per hectare)`))
## # A tibble: 13,075 × 14
##    Entity              Code   Year Wheat (tonnes per he…¹ Rice (tonnes per hec…²
##    <fct>               <fct> <dbl>                  <dbl>                  <dbl>
##  1 Puerto Rico         PRI    1961                 NA                       6.44
##  2 Spain               ESP    1961                  0.884                   6.36
##  3 Australia           AUS    1961                  1.13                    5.9 
##  4 Australia & New Ze… <NA>   1961                  1.16                    5.9 
##  5 Italy               ITA    1961                  1.91                    5.68
##  6 Southern Europe     <NA>   1961                  1.40                    5.42
##  7 Egypt               EGY    1961                  2.47                    5.05
##  8 Northern Africa     <NA>   1961                  0.696                   4.98
##  9 European Union      <NA>   1961                  1.86                    4.95
## 10 Japan               JPN    1961                  2.75                    4.88
## # ℹ 13,065 more rows
## # ℹ abbreviated names: ¹​`Wheat (tonnes per hectare)`,
## #   ²​`Rice (tonnes per hectare)`
## # ℹ 9 more variables: `Maize (tonnes per hectare)` <dbl>,
## #   `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>, …

Mutate

mutate adalah fungsi yang digunakan untuk membuat kolom atau variabel baru.

#Menghasilkan kolom baru bernama Wheat (kg per hectare)
mutate(df_crop, `Wheat (kg per hectare)` = `Wheat (tonnes per hectare)` * 1000)
## # A tibble: 13,075 × 15
##    Entity      Code   Year `Wheat (tonnes per hectare)` Rice (tonnes per hecta…¹
##    <fct>       <fct> <dbl>                        <dbl>                    <dbl>
##  1 Afghanistan AFG    1961                        1.02                      1.52
##  2 Afghanistan AFG    1962                        0.974                     1.52
##  3 Afghanistan AFG    1963                        0.832                     1.52
##  4 Afghanistan AFG    1964                        0.951                     1.73
##  5 Afghanistan AFG    1965                        0.972                     1.73
##  6 Afghanistan AFG    1966                        0.867                     1.52
##  7 Afghanistan AFG    1967                        1.12                      1.92
##  8 Afghanistan AFG    1968                        1.16                      1.95
##  9 Afghanistan AFG    1969                        1.19                      1.98
## 10 Afghanistan AFG    1970                        0.956                     1.81
## # ℹ 13,065 more rows
## # ℹ abbreviated name: ¹​`Rice (tonnes per hectare)`
## # ℹ 10 more variables: `Maize (tonnes per hectare)` <dbl>,
## #   `Soybeans (tonnes per hectare)` <dbl>,
## #   `Potatoes (tonnes per hectare)` <dbl>, `Beans (tonnes per hectare)` <dbl>,
## #   `Peas (tonnes per hectare)` <dbl>, `Cassava (tonnes per hectare)` <dbl>,
## #   `Barley (tonnes per hectare)` <dbl>, …

Kolom baru dengan kondisi

df_crop %>% 
  mutate(Wheat_Status = ifelse(`Wheat (tonnes per hectare)` > 1, "Lebih dari 1", "Kurang dari 1")) %>% select(Code,Year,Wheat_Status)
## # A tibble: 13,075 × 3
##    Code   Year Wheat_Status 
##    <fct> <dbl> <chr>        
##  1 AFG    1961 Lebih dari 1 
##  2 AFG    1962 Kurang dari 1
##  3 AFG    1963 Kurang dari 1
##  4 AFG    1964 Kurang dari 1
##  5 AFG    1965 Kurang dari 1
##  6 AFG    1966 Kurang dari 1
##  7 AFG    1967 Lebih dari 1 
##  8 AFG    1968 Lebih dari 1 
##  9 AFG    1969 Lebih dari 1 
## 10 AFG    1970 Kurang dari 1
## # ℹ 13,065 more rows

Summarise

summarise adalah fungsi yang digunakan untuk melakukan statistika deskriptif.

#ada dua summarise yang ingin dihasilkan
#gunakan na.rm = TRUE untuk meremove atau membuang nilai yang hilang
df_sum <- summarise(df_crop, 
                    `maksimum Wheat` = max(`Wheat (tonnes per hectare)`, na.rm = TRUE), 
                    `maksimum Rice` = max(`Rice (tonnes per hectare)`, na.rm = TRUE))
df_sum
## # A tibble: 1 × 2
##   `maksimum Wheat` `maksimum Rice`
##              <dbl>           <dbl>
## 1             10.7            10.7

Group by

Group by mengelompokan data dan menyimpulkannya. Untuk mengeksplorasi lebih lanjut, dapat ditambahkan fungsi fungsi lain.

#Memilih beberapa kolom awal, Mengelompokkan, kemudian menghitung rata rata, menyaring yang tidak kosong, menambahkan kolom baru, mengurutkan 
df_crop %>% 
  select(1:4) %>%
  group_by(Code) %>% 
  summarise(`Mean Wheat (tonnes per hectare)` = mean(`Wheat (tonnes per hectare)`)) %>%
  filter(!is.na(`Mean Wheat (tonnes per hectare)`))  %>%
  mutate(`Mean Wheat (kg per hectare)` = `Mean Wheat (tonnes per hectare)` * 1000) %>%
  arrange(desc(`Mean Wheat (kg per hectare)`))
## # A tibble: 118 × 3
##    Code  `Mean Wheat (tonnes per hectare)` `Mean Wheat (kg per hectare)`
##    <fct>                             <dbl>                         <dbl>
##  1 BEL                                8.54                         8544.
##  2 NLD                                7.03                         7030.
##  3 IRL                                6.83                         6830.
##  4 GBR                                6.37                         6366.
##  5 DNK                                6.18                         6175.
##  6 LUX                                5.98                         5977.
##  7 DEU                                5.89                         5894.
##  8 FRA                                5.65                         5645.
##  9 NZL                                5.36                         5358.
## 10 SWE                                5.18                         5179.
## # ℹ 108 more rows

Join

join adalah penggabungan tabel-tabel yang dapat dilakukan melalui kolom / key id yang memiliki nilai terkait untuk mendapatkan satu set data dengan informasi lengkap.

#Membuat tabel
# Tabel 1 Kualitas
tb_kualitas <- tibble(
  id_stasiun = c("ST01", "ST02", "ST03", "ST04"),
  tahun = c(2022, 2022, 2023, 2023),
  ph_air = c(6.5, 5.8, 7.0, 4.5),
  do_mg_l = c(5.2, 4.1, 6.5, 2.5)
)
# Tabel 2 Lokasi
tb_lokasi <- tibble(
  id_stasiun = c("ST01", "ST02", "ST05", "ST06"),
  tahun = c(2022, 2023, 2022, 2023), # ST02 beda tahun dengan tb_kualitas
  tipe_lahan = c("Gambut", "Lahan Basah", "Sungai", "Danau"),
  status_ekologi = c("Aman", "Waspada", "Aman", "Bahaya")
)
tb_kualitas
## # A tibble: 4 × 4
##   id_stasiun tahun ph_air do_mg_l
##   <chr>      <dbl>  <dbl>   <dbl>
## 1 ST01        2022    6.5     5.2
## 2 ST02        2022    5.8     4.1
## 3 ST03        2023    7       6.5
## 4 ST04        2023    4.5     2.5
tb_lokasi
## # A tibble: 4 × 4
##   id_stasiun tahun tipe_lahan  status_ekologi
##   <chr>      <dbl> <chr>       <chr>         
## 1 ST01        2022 Gambut      Aman          
## 2 ST02        2023 Lahan Basah Waspada       
## 3 ST05        2022 Sungai      Aman          
## 4 ST06        2023 Danau       Bahaya

Left Join mempertahankan semua baris dari tabel kiri (tb_kualitas). Kolom dari tabel kanan (tb_lokasi) hanya ditambahkan jika id_stasiun-nya cocok. Jika ada id_stasiun di tb_kualitas yang tidak ditemukan di tb_lokasi, nilainya akan menjadi NA. Argumen by menyatakan kolom kunci.

left_join(tb_kualitas, tb_lokasi, by = "id_stasiun")
## # A tibble: 4 × 7
##   id_stasiun tahun.x ph_air do_mg_l tahun.y tipe_lahan  status_ekologi
##   <chr>        <dbl>  <dbl>   <dbl>   <dbl> <chr>       <chr>         
## 1 ST01          2022    6.5     5.2    2022 Gambut      Aman          
## 2 ST02          2022    5.8     4.1    2023 Lahan Basah Waspada       
## 3 ST03          2023    7       6.5      NA <NA>        <NA>          
## 4 ST04          2023    4.5     2.5      NA <NA>        <NA>

Right Join mempertahankan semua baris dari tabel kanan (tb_lokasi). Kolom dari tb_kualitas hanya ditambahkan jika id_stasiun-nya cocok. Jika stasiun ada di tb_lokasi tapi belum ada datanya di tb_kualitas, nilainya menjadi NA.

right_join(tb_kualitas, tb_lokasi, by = "id_stasiun")
## # A tibble: 4 × 7
##   id_stasiun tahun.x ph_air do_mg_l tahun.y tipe_lahan  status_ekologi
##   <chr>        <dbl>  <dbl>   <dbl>   <dbl> <chr>       <chr>         
## 1 ST01          2022    6.5     5.2    2022 Gambut      Aman          
## 2 ST02          2022    5.8     4.1    2023 Lahan Basah Waspada       
## 3 ST05            NA   NA      NA      2022 Sungai      Aman          
## 4 ST06            NA   NA      NA      2023 Danau       Bahaya

Inner Join hanya menampilkan baris di mana id_stasiun ada di kedua tabel (tb_kualitas dan tb_lokasi). Baris yang tidak memiliki pasangan di tabel sebelahnya akan langsung dibuang.

inner_join(tb_kualitas, tb_lokasi, by = "id_stasiun")
## # A tibble: 2 × 7
##   id_stasiun tahun.x ph_air do_mg_l tahun.y tipe_lahan  status_ekologi
##   <chr>        <dbl>  <dbl>   <dbl>   <dbl> <chr>       <chr>         
## 1 ST01          2022    6.5     5.2    2022 Gambut      Aman          
## 2 ST02          2022    5.8     4.1    2023 Lahan Basah Waspada

full joinmenampilkan seluruh baris gabungan dari tb_kualitas dan tb_lokasi. Jika ada id_stasiun dari salah satu tabel yang tidak memiliki pasangan di tabel lainnya, kolom yang kosong tersebut akan diisi NA.

full_join(tb_kualitas, tb_lokasi, by = "id_stasiun")
## # A tibble: 6 × 7
##   id_stasiun tahun.x ph_air do_mg_l tahun.y tipe_lahan  status_ekologi
##   <chr>        <dbl>  <dbl>   <dbl>   <dbl> <chr>       <chr>         
## 1 ST01          2022    6.5     5.2    2022 Gambut      Aman          
## 2 ST02          2022    5.8     4.1    2023 Lahan Basah Waspada       
## 3 ST03          2023    7       6.5      NA <NA>        <NA>          
## 4 ST04          2023    4.5     2.5      NA <NA>        <NA>          
## 5 ST05            NA   NA      NA      2022 Sungai      Aman          
## 6 ST06            NA   NA      NA      2023 Danau       Bahaya

Penggabungan dengan dua kolom menggunakan by = c("id_stasiun", "tahun"). Baris dari tb_kualitas dan tb_lokasi hanya akan disatukan jika nilai id_stasiun DAN tahun cocok secara bersamaan (pada data ini, hanya ST01 yang berhasil bergabung).

inner_join(tb_kualitas, tb_lokasi, by = c("id_stasiun", "tahun"))
## # A tibble: 1 × 6
##   id_stasiun tahun ph_air do_mg_l tipe_lahan status_ekologi
##   <chr>      <dbl>  <dbl>   <dbl> <chr>      <chr>         
## 1 ST01        2022    6.5     5.2 Gambut     Aman

Praktik 1

Silahkan buat RMarkdown baru dan jawab setiap pertanyaan menggunakan fungsi-fungsi yang telah dipelajari pada RMarkdown tersebut dengan menampilkan kode dan outputnya. RMarkdown yang telah selesai lalu publikasi pada RPubs, dan link publikasi nya dapat dikirimkan di SIMARI pada tanggal 28 Mei 2026 dalam rentang 18.00-20.00 WITA.

  1. Menampilkan kolom Entity, Year, Potatoes, dan Cassava saja.
  2. Mengeliminasi kolom Soybeans, Beans, dan Peas dari tabel.
  3. Tahun berapa saja hasil panen padi (Rice) di Indonesia yang nilainya di bawah 2 ton?
  4. Negara apa saja yang punya hasil gandum (Wheat) di atas 5 ton pada tahun 2000 ke atas?
  5. Bagaimana cara memunculkan data negara Indonesia dan Malaysia khusus untuk tahun 2015 saja?
  6. Negara mana yang punya hasil jagung (Maize) paling rendah di tahun 2020?
  7. Mengurutkan data Indonesia dari hasil kentang (Potatoes) yang paling tinggi.
  8. Membuat kolom Rice_Status berisi teks “Tinggi” jika padi > 4 ton, dan “Rendah” jika di bawahnya.
  9. Berapa rata-rata hasil panen pisang (Bananas) di Indonesia dari seluruh tahun yang ada?
  10. Tampilkan data jagung mulai tahun 2010, lalu menghitung simpangan baku per negara, dan mengurutkannya dari nilai yang paling besar

Tidyr

Silakan perhatikan blok kode di bawah; baris #install.packages(“tidyverse”) diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan Tidyverse ini untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library(tidyverse) untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("tidyverse")
library(tidyverse)

tidyr salah satu paket dalam bahasa pemrograman R yang dirancang untuk merapikan dan membentuk ulang struktur dataset

# Persiapan Data
tb_lingkungan <- tibble(
  kode_area = c("ST01_Gambut_Aman", "ST02_Basah_Waspada", "ST03_Sungai_Aman", "ST04_Gambut_Bahaya", "ST05_Danau_Waspada", "ST06_Basah_Aman"),
  ph_Jan = c(6.5, 5.8, 7.0, 4.5, 6.8, 6.0),
  ph_Feb = c(6.2, 5.5, 6.8, 4.8, 6.9, 6.2),
  ph_Mar = c(6.4, 5.7, 7.1, 4.6, 6.7, 6.1)
)

tb_lingkungan
## # A tibble: 6 × 4
##   kode_area          ph_Jan ph_Feb ph_Mar
##   <chr>               <dbl>  <dbl>  <dbl>
## 1 ST01_Gambut_Aman      6.5    6.2    6.4
## 2 ST02_Basah_Waspada    5.8    5.5    5.7
## 3 ST03_Sungai_Aman      7      6.8    7.1
## 4 ST04_Gambut_Bahaya    4.5    4.8    4.6
## 5 ST05_Danau_Waspada    6.8    6.9    6.7
## 6 ST06_Basah_Aman       6      6.2    6.1

separate memecah satu kolom teks menjadi beberapa kolom baru. tb_lingkungan dimasukkan sebagai argumen pertama.Memecah teks pada kolom kode_area di tabel tb_lingkungan menjadi tiga kolom baru (id_stasiun, tipe_lahan, dan status) berdasarkan pemisah garis bawah (_).

#isi dalam kolom kode area dapat dipisah dengan separator "_"
tb_pisah <- separate(tb_lingkungan, col = kode_area, into = c("id_stasiun", "tipe_lahan", "status"), sep = "_")
tb_pisah
## # A tibble: 6 × 6
##   id_stasiun tipe_lahan status  ph_Jan ph_Feb ph_Mar
##   <chr>      <chr>      <chr>    <dbl>  <dbl>  <dbl>
## 1 ST01       Gambut     Aman       6.5    6.2    6.4
## 2 ST02       Basah      Waspada    5.8    5.5    5.7
## 3 ST03       Sungai     Aman       7      6.8    7.1
## 4 ST04       Gambut     Bahaya     4.5    4.8    4.6
## 5 ST05       Danau      Waspada    6.8    6.9    6.7
## 6 ST06       Basah      Aman       6      6.2    6.1

pivot_longer mengubah data dari format lebar seperti tb_pisah menjadi memanjang ke bawah.Mengubah tabel tb_pisah menjadi format panjang (long format) dengan melebur semua kolom ph_Jan, ph_Feb, ph_Mar ke dalam satu kolom baru bernama “bulan” dan memindahkan nilainya ke kolom “nilai_ph”.

tb_panjang <- pivot_longer(tb_pisah, cols = c("ph_Jan", "ph_Feb", "ph_Mar"), names_to = "bulan", values_to = "nilai_ph")
tb_panjang
## # A tibble: 18 × 5
##    id_stasiun tipe_lahan status  bulan  nilai_ph
##    <chr>      <chr>      <chr>   <chr>     <dbl>
##  1 ST01       Gambut     Aman    ph_Jan      6.5
##  2 ST01       Gambut     Aman    ph_Feb      6.2
##  3 ST01       Gambut     Aman    ph_Mar      6.4
##  4 ST02       Basah      Waspada ph_Jan      5.8
##  5 ST02       Basah      Waspada ph_Feb      5.5
##  6 ST02       Basah      Waspada ph_Mar      5.7
##  7 ST03       Sungai     Aman    ph_Jan      7  
##  8 ST03       Sungai     Aman    ph_Feb      6.8
##  9 ST03       Sungai     Aman    ph_Mar      7.1
## 10 ST04       Gambut     Bahaya  ph_Jan      4.5
## 11 ST04       Gambut     Bahaya  ph_Feb      4.8
## 12 ST04       Gambut     Bahaya  ph_Mar      4.6
## 13 ST05       Danau      Waspada ph_Jan      6.8
## 14 ST05       Danau      Waspada ph_Feb      6.9
## 15 ST05       Danau      Waspada ph_Mar      6.7
## 16 ST06       Basah      Aman    ph_Jan      6  
## 17 ST06       Basah      Aman    ph_Feb      6.2
## 18 ST06       Basah      Aman    ph_Mar      6.1

pivot_wider() Kebalikan dari pivot_longer(). Mengubah data memanjang ke bawah seperti tb_panjang kembali menjadi lebar.

tb_lebar_kembali <- pivot_wider(tb_panjang, names_from = "bulan", values_from = "nilai_ph")
tb_lebar_kembali
## # A tibble: 6 × 6
##   id_stasiun tipe_lahan status  ph_Jan ph_Feb ph_Mar
##   <chr>      <chr>      <chr>    <dbl>  <dbl>  <dbl>
## 1 ST01       Gambut     Aman       6.5    6.2    6.4
## 2 ST02       Basah      Waspada    5.8    5.5    5.7
## 3 ST03       Sungai     Aman       7      6.8    7.1
## 4 ST04       Gambut     Bahaya     4.5    4.8    4.6
## 5 ST05       Danau      Waspada    6.8    6.9    6.7
## 6 ST06       Basah      Aman       6      6.2    6.1

unite kebalikan dari separate(). Menggabungkan beberapa kolom seperti pada tabel tb_pisah menjadi satu kolom teks.Menggabungkan kolom id_stasiun dan tipe_lahan pada tabel tb_pisah menjadi satu kolom baru bernama id_lengkap dengan menggunakan tanda hubung (-) sebagai pemisah.

tb_gabung <- unite(tb_pisah, col = "id_lengkap", "id_stasiun", "tipe_lahan", sep = "-")
tb_gabung
## # A tibble: 6 × 5
##   id_lengkap  status  ph_Jan ph_Feb ph_Mar
##   <chr>       <chr>    <dbl>  <dbl>  <dbl>
## 1 ST01-Gambut Aman       6.5    6.2    6.4
## 2 ST02-Basah  Waspada    5.8    5.5    5.7
## 3 ST03-Sungai Aman       7      6.8    7.1
## 4 ST04-Gambut Bahaya     4.5    4.8    4.6
## 5 ST05-Danau  Waspada    6.8    6.9    6.7
## 6 ST06-Basah  Aman       6      6.2    6.1

Forcats

Silakan perhatikan blok kode di bawah; baris #install.packages(“tidyverse”) diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan Tidyverse ini untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library(tidyverse) untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("tidyverse")
library(tidyverse)

forcats digunakan untuk mengorganisir data kategorik (factor) seperti melihat level factor, merubah urutan level factor, merubah level factor, menggabungkan level factor, dan lain sebagainya.

#Membuat data
set.seed(123)
tb_mentah <- tibble(
  id_lokasi = 1:10,
  status_banjir = sample(c("Aman", "Waspada", "Bahaya"), 10, replace = TRUE), # Tipe chr
  jenis_tanah = sample(c("Gambut", "Aluvial"), 10, replace = TRUE) # Tipe chr
)

#perhatikan disini kolom masih bertipe karakter
tb_mentah
## # A tibble: 10 × 3
##    id_lokasi status_banjir jenis_tanah
##        <int> <chr>         <chr>      
##  1         1 Bahaya        Aluvial    
##  2         2 Bahaya        Aluvial    
##  3         3 Bahaya        Aluvial    
##  4         4 Waspada       Gambut     
##  5         5 Bahaya        Aluvial    
##  6         6 Waspada       Gambut     
##  7         7 Waspada       Aluvial    
##  8         8 Waspada       Gambut     
##  9         9 Bahaya        Gambut     
## 10        10 Aman          Gambut
summary(tb_mentah)
##    id_lokasi     status_banjir      jenis_tanah       
##  Min.   : 1.00   Length:10          Length:10         
##  1st Qu.: 3.25   Class :character   Class :character  
##  Median : 5.50   Mode  :character   Mode  :character  
##  Mean   : 5.50                                        
##  3rd Qu.: 7.75                                        
##  Max.   :10.00

Mengubah tipe Karakter (chr) menjadi Faktor (fct). Memodifikasi tabel tb_mentah menjadi tb_banjir dengan mengubah tipe data kolom status_banjir menjadi faktor berurutan spesifik (“Aman” hingga “Kritis”) dan kolom jenis_tanah menjadi faktor biasa.

# disini dicoba tambahkan level baru kritis
tb_banjir <- mutate(tb_mentah, 
  status_banjir = factor(status_banjir, levels = c("Aman", "Waspada", "Bahaya", "Kritis")),
  jenis_tanah = as.factor(jenis_tanah)
)

tb_banjir
## # A tibble: 10 × 3
##    id_lokasi status_banjir jenis_tanah
##        <int> <fct>         <fct>      
##  1         1 Bahaya        Aluvial    
##  2         2 Bahaya        Aluvial    
##  3         3 Bahaya        Aluvial    
##  4         4 Waspada       Gambut     
##  5         5 Bahaya        Aluvial    
##  6         6 Waspada       Gambut     
##  7         7 Waspada       Aluvial    
##  8         8 Waspada       Gambut     
##  9         9 Bahaya        Gambut     
## 10        10 Aman          Gambut
#kolom faktor sudah memiliki informasi jumlah
summary(tb_banjir)
##    id_lokasi     status_banjir  jenis_tanah
##  Min.   : 1.00   Aman   :1     Aluvial:5   
##  1st Qu.: 3.25   Waspada:4     Gambut :5   
##  Median : 5.50   Bahaya :5                 
##  Mean   : 5.50   Kritis :0                 
##  3rd Qu.: 7.75                             
##  Max.   :10.00

fct_count menghitung jumlah kemunculan tiap level pada kolom status_banjir di data tb_banjir, termasuk level yang jumlahnya nol (seperti "Kritis").

fct_count(tb_banjir$status_banjir)
## # A tibble: 4 × 2
##   f           n
##   <fct>   <int>
## 1 Aman        1
## 2 Waspada     4
## 3 Bahaya      5
## 4 Kritis      0

fct_relevel mengubah urutan level secara manual. Di sini, dapat diubah level.

#hasilnya disimpan di var_relevel
var_relevel <- fct_relevel(tb_banjir$status_banjir, "Aman","Kritis", "Waspada","Bahaya" )
levels(var_relevel)
## [1] "Aman"    "Kritis"  "Waspada" "Bahaya"

fct_rev membalikkan urutan level pada status_banjir dari belakang ke depan

# hasilnya disimpan di var_fct
var_fct <-fct_rev(tb_banjir$status_banjir)
levels(var_fct)
## [1] "Kritis"  "Bahaya"  "Waspada" "Aman"

fct_expand menambahkan level kategori baru ("Darurat") ke dalam kolom status_banjir meskipun belum ada observasinya.

#hasilnya akan mengubah kolom status banjir pada tb_banjir 
tb_banjir$status_banjir<-fct_expand(tb_banjir$status_banjir, "Darurat")
summary(tb_banjir)
##    id_lokasi     status_banjir  jenis_tanah
##  Min.   : 1.00   Aman   :1     Aluvial:5   
##  1st Qu.: 3.25   Waspada:4     Gambut :5   
##  Median : 5.50   Bahaya :5                 
##  Mean   : 5.50   Kritis :0                 
##  3rd Qu.: 7.75   Darurat:0                 
##  Max.   :10.00

fct_drop membuang level dari status_banjir yang tidak memiliki data observasi

tb_banjir$status_banjir<-fct_drop(tb_banjir$status_banjir)
summary(tb_banjir)
##    id_lokasi     status_banjir  jenis_tanah
##  Min.   : 1.00   Aman   :1     Aluvial:5   
##  1st Qu.: 3.25   Waspada:4     Gambut :5   
##  Median : 5.50   Bahaya :5                 
##  Mean   : 5.50                             
##  3rd Qu.: 7.75                             
##  Max.   :10.00

fct_collapse menggabungkan beberapa level di status_banjir menjadi satu level baru. Menggabungkan "Waspada" dan "Bahaya" menjadi "Khusus".

tb_banjir$status_banjir<-fct_collapse(tb_banjir$status_banjir, Khusus = c("Waspada", "Bahaya"))
summary(tb_banjir)
##    id_lokasi     status_banjir  jenis_tanah
##  Min.   : 1.00   Aman  :1      Aluvial:5   
##  1st Qu.: 3.25   Khusus:9      Gambut :5   
##  Median : 5.50                             
##  Mean   : 5.50                             
##  3rd Qu.: 7.75                             
##  Max.   :10.00
tb_banjir
## # A tibble: 10 × 3
##    id_lokasi status_banjir jenis_tanah
##        <int> <fct>         <fct>      
##  1         1 Khusus        Aluvial    
##  2         2 Khusus        Aluvial    
##  3         3 Khusus        Aluvial    
##  4         4 Khusus        Gambut     
##  5         5 Khusus        Aluvial    
##  6         6 Khusus        Gambut     
##  7         7 Khusus        Aluvial    
##  8         8 Khusus        Gambut     
##  9         9 Khusus        Gambut     
## 10        10 Aman          Gambut

fct_recode mengubah nama level spesifik secara manual di status_banjir. Mengganti nama level "Aman" menjadi "Normal".

tb_banjir$status_banjir<-fct_recode(tb_banjir$status_banjir, Normal = "Aman")
tb_banjir
## # A tibble: 10 × 3
##    id_lokasi status_banjir jenis_tanah
##        <int> <fct>         <fct>      
##  1         1 Khusus        Aluvial    
##  2         2 Khusus        Aluvial    
##  3         3 Khusus        Aluvial    
##  4         4 Khusus        Gambut     
##  5         5 Khusus        Aluvial    
##  6         6 Khusus        Gambut     
##  7         7 Khusus        Aluvial    
##  8         8 Khusus        Gambut     
##  9         9 Khusus        Gambut     
## 10        10 Normal        Gambut

Lubridate

Silakan perhatikan blok kode di bawah; baris #install.packages(“tidyverse”) diawali dengan tanda pagar (#) yang berarti baris tersebut saat ini berstatus sebagai komentar dan tidak akan dijalankan oleh R. Jika ini adalah pertama kali kalian menggunakan Tidyverse ini untuk praktikum, silakan hapus tanda pagar tersebut terlebih dahulu untuk menginstal package, namun jika sudah pernah terinstal, biarkan tanda pagar tersebut tetap ada agar R langsung menjalankan perintah library(tidyverse) untuk mengaktifkan fungsinya tanpa melakukan proses instalasi ulang yang memakan waktu.

#install.packages("tidyverse")
library(tidyverse)

lubridate adalah suatu package yang digunakan untuk mengorganisir data tanggal dan waktu. Selain itu package ini juga bisa melakukan operasi aritmatika terhadap tanggal dan waktu.

tb_waktu <- tibble(
  id_lokasi = 1:5,
  tgl_ymd = c("2026-01-15", "2026-02-20", "2026-03-10", "2026-04-05", "2026-05-12"),
  tgl_mdy = c("01/15/2026", "02/20/2026", "03/10/2026", "04/05/2026", "05/12/2026"),
  tgl_dmy = c("15-01-2026", "20-02-2026", "10-03-2026", "05-04-2026", "12-05-2026"),
  waktu_pantau = c("2026-01-15 08:30:00", "2026-02-20 14:15:00", "2026-03-10 10:45:00", "2026-04-05 09:00:00", "2026-05-12 16:20:00")
)
#disini waktu masih berbentuk karakter
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <chr>      <chr>      <chr>      <chr>              
## 1         1 2026-01-15 01/15/2026 15-01-2026 2026-01-15 08:30:00
## 2         2 2026-02-20 02/20/2026 20-02-2026 2026-02-20 14:15:00
## 3         3 2026-03-10 03/10/2026 10-03-2026 2026-03-10 10:45:00
## 4         4 2026-04-05 04/05/2026 05-04-2026 2026-04-05 09:00:00
## 5         5 2026-05-12 05/12/2026 12-05-2026 2026-05-12 16:20:00

Mengonversi tipe Karakter (chr) menjadi Datetime. Disini kolom waktu_pantau terjadi perubahan tipe.

tb_waktu$waktu_pantau <- ymd_hms(tb_waktu$waktu_pantau)
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <chr>      <chr>      <chr>      <dttm>             
## 1         1 2026-01-15 01/15/2026 15-01-2026 2026-01-15 08:30:00
## 2         2 2026-02-20 02/20/2026 20-02-2026 2026-02-20 14:15:00
## 3         3 2026-03-10 03/10/2026 10-03-2026 2026-03-10 10:45:00
## 4         4 2026-04-05 04/05/2026 05-04-2026 2026-04-05 09:00:00
## 5         5 2026-05-12 05/12/2026 12-05-2026 2026-05-12 16:20:00

Menampilkan tanggal hari ini berdasarkan pengaturan sistem komputer.

today()
## [1] "2026-05-25"

Menampilkan tanggal dan waktu saat ini secara detail, beserta zona waktu yang berlaku.

now()
## [1] "2026-05-25 12:22:19 WITA"

Mengecek nama zona waktu (timezone) default yang sedang aktif di sistem.

Sys.timezone()
## [1] "Asia/Makassar"

Menampilkan daftar lengkap nama zona waktu yang valid di seluruh dunia. Kita gunakan head() agar output tidak terlalu panjang.

head(OlsonNames())
## [1] "Africa/Abidjan"     "Africa/Accra"       "Africa/Addis_Ababa"
## [4] "Africa/Algiers"     "Africa/Asmara"      "Africa/Asmera"

Mengubah teks berformat Year-Month-Day (Tahun-Bulan-Tanggal) pada kolom tgl_ymd menjadi tipe data Date.

# perhatikan kolom tgl_ymd
tb_waktu$tgl_ymd<-ymd(tb_waktu$tgl_ymd)
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <date>     <chr>      <chr>      <dttm>             
## 1         1 2026-01-15 01/15/2026 15-01-2026 2026-01-15 08:30:00
## 2         2 2026-02-20 02/20/2026 20-02-2026 2026-02-20 14:15:00
## 3         3 2026-03-10 03/10/2026 10-03-2026 2026-03-10 10:45:00
## 4         4 2026-04-05 04/05/2026 05-04-2026 2026-04-05 09:00:00
## 5         5 2026-05-12 05/12/2026 12-05-2026 2026-05-12 16:20:00

Mengubah teks berformat Month-Day-Year (Bulan-Tanggal-Tahun) pada kolom tgl_mdy menjadi tipe data Date.

# perhatikan kolom tgl_mdy
tb_waktu$tgl_mdy<-mdy(tb_waktu$tgl_mdy)
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <date>     <date>     <chr>      <dttm>             
## 1         1 2026-01-15 2026-01-15 15-01-2026 2026-01-15 08:30:00
## 2         2 2026-02-20 2026-02-20 20-02-2026 2026-02-20 14:15:00
## 3         3 2026-03-10 2026-03-10 10-03-2026 2026-03-10 10:45:00
## 4         4 2026-04-05 2026-04-05 05-04-2026 2026-04-05 09:00:00
## 5         5 2026-05-12 2026-05-12 12-05-2026 2026-05-12 16:20:00

Mengubah teks berformat Day-Month-Year (Tanggal-Bulan-Tahun) pada kolom tgl_dmy menjadi tipe data Date.

tb_waktu$tgl_dmy<-dmy(tb_waktu$tgl_dmy)
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <date>     <date>     <date>     <dttm>             
## 1         1 2026-01-15 2026-01-15 2026-01-15 2026-01-15 08:30:00
## 2         2 2026-02-20 2026-02-20 2026-02-20 2026-02-20 14:15:00
## 3         3 2026-03-10 2026-03-10 2026-03-10 2026-03-10 10:45:00
## 4         4 2026-04-05 2026-04-05 2026-04-05 2026-04-05 09:00:00
## 5         5 2026-05-12 2026-05-12 2026-05-12 2026-05-12 16:20:00

Mengambil komponen spesifik dari data tanggal/waktu yang sudah berbentuk Datetime (waktu_pantau), seperti mengekstrak jam atau bulan.

# Mengambil komponen jam pengamatan
hour(tb_waktu$waktu_pantau)
## [1]  8 14 10  9 16
# Mengambil komponen bulan pengamatan dengan nama label
month(tb_waktu$waktu_pantau, label = TRUE)
## [1] Jan Feb Mar Apr May
## 12 Levels: Jan < Feb < Mar < Apr < May < Jun < Jul < Aug < Sep < ... < Dec

Melakukan perhitungan matematika pada waktu. Di sini kita menambahkan durasi 7 hari (1 minggu) pada waktu_pantau untuk jadwal pengamatan berikutnya.

# Menambahkan 7 hari menggunakan fungsi days() pada kolom waktu pantau
tb_waktu$waktu_pantau<-tb_waktu$waktu_pantau + days(7)
tb_waktu
## # A tibble: 5 × 5
##   id_lokasi tgl_ymd    tgl_mdy    tgl_dmy    waktu_pantau       
##       <int> <date>     <date>     <date>     <dttm>             
## 1         1 2026-01-15 2026-01-15 2026-01-15 2026-01-22 08:30:00
## 2         2 2026-02-20 2026-02-20 2026-02-20 2026-02-27 14:15:00
## 3         3 2026-03-10 2026-03-10 2026-03-10 2026-03-17 10:45:00
## 4         4 2026-04-05 2026-04-05 2026-04-05 2026-04-12 09:00:00
## 5         5 2026-05-12 2026-05-12 2026-05-12 2026-05-19 16:20:00