library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.2
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6      ✔ purrr   0.3.5 
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ tidyr   1.2.1      ✔ stringr 1.4.1 
## ✔ readr   2.1.4      ✔ forcats 0.5.2
## Warning: package 'readr' was built under R version 4.2.3
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(nycflights13)
## Warning: package 'nycflights13' was built under R version 4.2.3
library(Lahman)
## Warning: package 'Lahman' was built under R version 4.2.3

Membuat Variabel Baru dari yang Lama Pada Transformasi Data

Seringkali perlu menggunakan variabel dalam kumpulan data untuk membuat variabel baru. Fungsi transformasi yang digunakan untuk melakukan ini adalah mutate.

Misalnya, kita mungkin ingin menambahkan kolom yang flightsberisi kecepatan udara rata-rata setiap penerbangan. Mengingat bahwa kecepatan rata-rata adalah jarak total dibagi waktu total, kita dapat menghitung kecepatan udara penerbangan dengan menghitung distance / air_time. Hampir saja. Satuannya distanceadalah mil, dan satuannya air_timeadalah menit, jadi untuk menghitung kecepatan udara dalam satuan mil per jam yang lebih familiar, kita sebenarnya ingin menghitung distance / air_time * 60.

Untuk membuat perhitungan ini untuk setiap baris flightsdan menambahkannya sebagai kolom baru (sebut saja kolom baru ini air_speed), kami menerapkan mutatefungsi sebagai berikut:

flights %>%
  mutate(air_speed = distance / air_time * 60)
## # A tibble: 336,776 × 20
##     year month   day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
##    <int> <int> <int>    <int>      <int>   <dbl>   <int>   <int>   <dbl> <chr>  
##  1  2013     1     1      517        515       2     830     819      11 UA     
##  2  2013     1     1      533        529       4     850     830      20 UA     
##  3  2013     1     1      542        540       2     923     850      33 AA     
##  4  2013     1     1      544        545      -1    1004    1022     -18 B6     
##  5  2013     1     1      554        600      -6     812     837     -25 DL     
##  6  2013     1     1      554        558      -4     740     728      12 UA     
##  7  2013     1     1      555        600      -5     913     854      19 B6     
##  8  2013     1     1      557        600      -3     709     723     -14 EV     
##  9  2013     1     1      557        600      -3     838     846      -8 B6     
## 10  2013     1     1      558        600      -2     753     745       8 AA     
## # … with 336,766 more rows, 10 more variables: flight <int>, tailnum <chr>,
## #   origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## #   minute <dbl>, time_hour <dttm>, air_speed <dbl>, and abbreviated variable
## #   names ¹​sched_dep_time, ²​dep_delay, ³​arr_time, ⁴​sched_arr_time, ⁵​arr_delay

Saat memutasi variabel baru ke kumpulan data, praktik yang lebih baik adalah menetapkan nama baru untuk kumpulan data yang dimutasi. Anda dapat melakukannya dengan memasukkan penetapan nama <NEW NAME> <-di awal kode di atas:

flights_w_speed <- flights %>%
  mutate(air_speed = distance / air_time * 60)

Anda sekarang dapat merujuk ke flights_w_speeduntuk analisis selanjutnya.

Argumen dari mutateselalu berbentuk:

<NEW VARIABLE NAME> = <FORMULA INVOLVING OLD VARIABLES>

Rumusnya sering dibangun menggunakan aritmatika dasar, seperti perhitungan kecepatan udara di atas. Namun, ada baiknya menyebutkan beberapa operasi lain yang berguna untuk digunakan dalam rumus.

Jalankan baris kode berikut, dan coba tebak apa yang dilakukan operator %/%and %%:

27 %/% 4 
27 %% 4

Anda mungkin telah menebak bahwa %/%mengembalikan hasil bagi bilangan bulat yang diperoleh saat membagi satu angka dengan angka lainnya, sambil %%mengembalikan sisanya. Kita dapat langsung melihat bagaimana operasi ini dapat diterapkan dengan melakukan hal berikut: Tambahkan kolom yang flightsmenghitung jumlah menit sejak tengah malam hingga setiap penerbangan berangkat dan kolom lain yang menghitung jumlah menit sejak tengah malam hingga setiap penerbangan tiba.

Misalnya, untuk penerbangan pertama dalam kumpulan data, nilai dari dep_timeadalah 517, dan nilai dari arr_timeadalah 830. Angka-angka ini sebenarnya hanyalah singkatan dari 5:17am dan 8:30am, dan bukan angka yang bisa langsung digunakan. dalam perhitungan. Mengubah waktu ini menjadi menit sejak tengah malam akan memberikan pengukuran numerik aktual (bukan waktu) yang menunjukkan kapan penerbangan berangkat atau tiba.

Untuk waktu keberangkatan 5:17, kita akan mengonversi ke menit sejak tengah malam dengan menghitung 5*60 + 17, yaitu 317. Tapi bagaimana kita memberitahu R untuk melakukan ini? Kami harus memiliki cara untuk memisahkan satu atau dua digit pertama dari dua digit terakhir. Di sinilah %/%dan %%masuk: Perhatikan bahwa 517 %/% 100 = 5dan 517 %% 100 = 17. Dengan demikian, konversi dapat dilakukan dengan rumus (517 %/% 100)*60 + (517 %% 100).

Kami sekarang dapat menambahkan menit kami sejak variabel tengah malam sebagai berikut. (Perhatikan bahwa Anda dapat membuat lebih dari satu variabel baru dalam satu mutatepanggilan.) Kami juga akan memilih kolom yang relevan sehingga terlihat di output.

flights_w_mins_midnight <- flights %>%
  mutate(dep_mins_midnight = (dep_time %/% 100)*60 + (dep_time %% 100),
         arr_mins_midnight = (arr_time %/% 100)*60 + (arr_time %% 100)) %>%
  select(dep_time, dep_mins_midnight, arr_time, arr_mins_midnight)

flights_w_mins_midnight
## # A tibble: 336,776 × 4
##    dep_time dep_mins_midnight arr_time arr_mins_midnight
##       <int>             <dbl>    <int>             <dbl>
##  1      517               317      830               510
##  2      533               333      850               530
##  3      542               342      923               563
##  4      544               344     1004               604
##  5      554               354      812               492
##  6      554               354      740               460
##  7      555               355      913               553
##  8      557               357      709               429
##  9      557               357      838               518
## 10      558               358      753               473
## # … with 336,766 more rows

Operasi lain yang sangat berguna untuk digunakan dalam mutaterumus adalah ifelse. Fungsi ifelsemengembalikan nilai yang bergantung pada kebenaran atau kepalsuan dari suatu kondisi. Sintaks dasarnya adalah

ifelse(<CONDITION>, 
<VALUE IF CONDITION IS TRUE>,        <VALUE IF CONDITION IS FALSE)

Misalnya, di ifelsebawah ini mengatakan untuk memeriksa apakah x < y. Jika ya, maka kembalikan nilai x^2. Jika tidak, kembalikan string “halo”.

x <- 4
y <- 2

ifelse(x < y, 
       x^2, 
       "halo")
## [1] "halo"

ifelsepernyataan dapat digunakan di dalam mutateuntuk membuat variabel baru dengan cara yang bergantung pada kondisi pada variabel lama. Ini adalah cara yang sangat berguna untuk mengkategorikan variabel kontinu, misalnya, untuk menetapkan nilai kategorikal ke variabel kontinu. Misalnya, mungkin kita ingin menambahkan kolom yang flightsmenyatakan apakah penerbangan tiba terlambat atau tepat waktu (atau lebih awal). (Kami hanya akan memilih kolom yang relevan untuk membuat kolom baru kami terlihat.)

flights_w_arr_status <- flights %>%
  mutate(arr_status = ifelse(arr_delay <= 0, 
                             "on time", 
                             "late")) %>%
  select(month, day, arr_delay, origin, dest, arr_status)

flights_w_arr_status
## # A tibble: 336,776 × 6
##    month   day arr_delay origin dest  arr_status
##    <int> <int>     <dbl> <chr>  <chr> <chr>     
##  1     1     1        11 EWR    IAH   late      
##  2     1     1        20 LGA    IAH   late      
##  3     1     1        33 JFK    MIA   late      
##  4     1     1       -18 JFK    BQN   on time   
##  5     1     1       -25 LGA    ATL   on time   
##  6     1     1        12 EWR    ORD   late      
##  7     1     1        19 EWR    FLL   late      
##  8     1     1       -14 LGA    IAD   on time   
##  9     1     1        -8 JFK    MCO   on time   
## 10     1     1         8 LGA    ORD   late      
## # … with 336,766 more rows

Pernyataan sederhana ifelseseperti di atas bekerja dengan baik saat membuat variabel kategori biner (dua nilai) seperti status kedatangan penerbangan. Namun, untuk membuat variabel kategorikal dengan lebih dari dua kemungkinan nilai, ifelsetidaklah ideal.

Misalkan kita ingin melakukan kembali kategorisasi di atas tetapi dengan tambahan kategori “dibatalkan” untuk penerbangan dengan tanda NAdi arr_delaykolom. Salah satu cara (tidak optimal) untuk melakukan ini adalah dengan pernyataan bersarang ifelse . Logikanya akan bekerja seperti ini: Pertama, periksa apakah arr_delayitu NA. Jika ya, tetapkan nilai “dibatalkan”. Jika tidak, maka kami belum siap untuk menetapkan nilai karena masih bisa “tepat waktu” atau “terlambat”. Kami memiliki lebih banyak pemeriksaan yang harus dilakukan. Jadi, dalam argumen ketiga kita ifelse, kita harus memulai yang baru ifelse. Ini baru ifelseakan memeriksa apakah arr_delaynegatif atau 0. Jika ya, kami akan menetapkan “tepat waktu”. Jika tidak, satu-satunya pilihan yang tersisa adalah arr_delaypositif, jadi kami akan menetapkan “terlambat”. Itufilterpada akhirnya adalah untuk memastikan bahwa nilai “dibatalkan” benar-benar muncul di keluaran yang terlihat.

flights_w_arr_status2 <- flights %>%
  mutate(arr_status = ifelse(is.na(arr_delay), 
                             "canceled",
                             ifelse(arr_delay <= 0,
                                    "on time",
                                    "late"))) %>%
  select(month, day, arr_delay, origin, dest, arr_status) %>%
  filter(row_number() >= 611)

flights_w_arr_status2
## # A tibble: 336,166 × 6
##    month   day arr_delay origin dest  arr_status
##    <int> <int>     <dbl> <chr>  <chr> <chr>     
##  1     1     1        46 JFK    RSW   late      
##  2     1     1       -12 EWR    PBI   on time   
##  3     1     1         3 LGA    DTW   late      
##  4     1     1       -21 JFK    PDX   on time   
##  5     1     1        68 LGA    MIA   late      
##  6     1     1        NA LGA    XNA   canceled  
##  7     1     1       -24 LGA    MCO   on time   
##  8     1     1        66 JFK    RDU   late      
##  9     1     1        -2 EWR    MCO   on time   
## 10     1     1        27 JFK    TPA   late      
## # … with 336,156 more rows

Ada beberapa masalah dengan ini, yang paling jelas adalah bahwa ifelsepernyataan bersarang sulit dibaca, terutama bila ada banyak kategori. (Di atas hanya memiliki tiga kategori dan sudah sangat berantakan dengan tanda kurung.) Masalah lain adalah bahwa ifelsepernyataan bersarang bergantung pada urutan pemeriksaan kondisi. Salah satu latihan untuk bagian ini akan mengilustrasikan apa yang terjadi jika kondisi NAdi atas tidak diperiksa terlebih dahulu.

Ada opsi yang jauh lebih baik untuk kategorisasi dengan lebih dari dua kategori: case_when. Begini cara kerjanya:

flights_w_arr_status3 <- flights %>%
  mutate(arr_status = case_when(is.na(arr_delay) ~ "canceled",
                                arr_delay <= 0 ~ "on time",
                                arr_delay >0 ~ "late")) %>%
  select(month, day, arr_delay, origin, dest, arr_status) %>%
  filter(row_number() >= 611)

flights_w_arr_status3
## # A tibble: 336,166 × 6
##    month   day arr_delay origin dest  arr_status
##    <int> <int>     <dbl> <chr>  <chr> <chr>     
##  1     1     1        46 JFK    RSW   late      
##  2     1     1       -12 EWR    PBI   on time   
##  3     1     1         3 LGA    DTW   late      
##  4     1     1       -21 JFK    PDX   on time   
##  5     1     1        68 LGA    MIA   late      
##  6     1     1        NA LGA    XNA   canceled  
##  7     1     1       -24 LGA    MCO   on time   
##  8     1     1        66 JFK    RDU   late      
##  9     1     1        -2 EWR    MCO   on time   
## 10     1     1        27 JFK    TPA   late      
## # … with 336,156 more rows