class: center, top, title-slide .title[ # İLT668, Üçüncü Ders ] .subtitle[ ## Tidyverse Paketleriyle Veri Manipülasyonu I: Pipe Operatörü, Select ve Filter ] .author[ ### Umut Yener Kara ] .date[ ### 19 Mart, 2023
Güncelleme: Mar 21, 2023 ] --- class: inverse #.left[Tidyverse ile Veri Manipülasyonu I] --- ##.left[Veri Düzenleme ve Veri Manipülasyonu (Data Wrangling)] Niceliksel ve bilgisayar tabanlı araştırmaların büyük bölümü çeşitli veri düzenleme işlemleri gerektirir. Veri toplama, R'a veri aktarma, verilerdeki hataları tespit etme, verileri temizleme, keşfetme, görselleştirme, analiz etme ve sonuçları raporlama gibi pek çok süreç bir düzeyde veri manipülasyonu gerektirecektir. Öyle ki klişeleşmiş bir söze göre veri analistlerinin zamanının %90'a kadar bir kısmı veri düzenlemeyle geçmektedir. -- Tidyverse bu süreçleri kolaylaştırmak için ortak ilkelere, gramere ve veri yapılarına göre tasarlanmış R paketlerdir. -- Tidy paketleri düzenli veya "tidy" formata sahip veri çerçeveleri üzerine kuruludurlar. Ana mantıkları: * Tolstoy: "Mutlu aileler birbirine benzerler, her mutsuz aileninse kendine özgü bir mutsuzluğu vardır." * Wickham: "Düzenli veri setleri birbirine benzerler, her düzensiz veri setininse kendine özgü bir düzensizliği vardır." -- Tidy formatının üç temel ilkesi vardır: * Her değişkenin tek bir sütunu olmalıdır. * Her gözlemin tek bir satırı olmalıdır. * Her değerin tek bir hücresi olmalıdır. --- ##.left[Düzenli (Tidy) Veri Çerçeveleri] <img src="data:image/png;base64,#images/tidy_format.png" width="80%" style="display: block; margin: auto;" /> <img src="data:image/png;base64,#images/messy_tidy.png" width="80%" style="display: block; margin: auto;" /> --- ##.left[Düzensiz Veriden Düzenli Veriye] <img src="data:image/png;base64,#images/tidy.png" width="100%" style="display: block; margin: auto;" /> --- ##.left[Tidyverse Ekosistemi] <img src="data:image/png;base64,#images/tidyverse-packages.png" width="100%" style="display: block; margin: auto;" /> --- class: inverse #.left[`dplyr` Paketiyle Veri Çerçevelerini Düzenlemek] * `select()` * `pipe (%>%) operatörü` * `filter()` --- ##.left[`nycflights13` Veri Seti] Bu derste örnekler için New York havalimanının 2013 yılı için uçuş kayıtlarını içeren [`nycflights13` paketini](https://cran.r-project.org/web/packages/nycflights13/nycflights13.pdf) kullanacağız. ```r install.packages("nycflights13") library(nycflights13) ``` Paket beş veri seti içermektedir: * `flights`: JFK, LGA, veya EWR havalimanlarının kalkış ve iniş verileri * `airlines`: havayolu şirketi kısaltmaları * `airports`: havalimanı verileri * `planes`: uçak verileri * `weather`: hava durumu verileri Bunlardan derste `flights` veri setini kullanacağız. ```r data(flights) glimpse(flights) ``` --- ##.left[Veri Çerçevelerinde Sütun Seçmek: `select()`] **`select()`** fonksiyonuyla bir veri çerçevesinin sütunlarını ismiyle veya sıra numarasıyla seçebiliriz. ```r select(flights, 1:5) # ilk 5 sütunu (değişkeni) seçme select(flights, year, month, dep_time) # yıl, ay ve kalkış saati sütunlarını seçme select(flights, year:dep_time) # yıl ve kalkış saati arasındaki (bunlar dahil) değişkenleri seçme ``` Eksi (`-`) işaretiyle belirtilen sütunları kaldırabiliriz. ```r select(flights, -1) #ilk sütun olan `year` sütununu sildik select(flights, -(year:dep_time)) # yıl ve kakış saati arasındaki sütunları kaldırır ``` --- ##.left[Yardımcı `select()` Fonksiyonları] `select()` fonksiyonun `starts_with()`, `ends_with()` ve `contains()` gibi pek çok yardımcı fonksiyonu vardır. Daha fazla fonksiyon ve yardım için **?select** komutunu kullanın. Bu fonksiyonlar sütun isimlerindeki eşleşmelerle seçim yapıp, koşulu sağlayan sütunları getireceklerdir. Bu fonksiyonlar belli bir örüntüye ve düzene sahip çok sayıda sütuna sahip "geniş" (wide) veri setleri için bilhassa kullanışlıdır. ```r select(flights, starts_with("time")) # time kelimesi ile başlayan sütunları seçme select(flights, ends_with("time")) # time kelimesi ile biten sütunlar seçme select(flights, -ends_with("time")) # time kelimesi ile bitmeyen sütunları seçme select(flights, contains("TIME")) # TIME kelimesi içeren sütunları seçme select(flights, contains("TIME", ignore.case=TRUE)) # büyük küçük harfe duyarsız bir şekilde, time geçen sütunları seçme ``` Diğer yardımcı bir fonksiyon olan `where()` değişken/sütun veri tipine göre seçim yapmayı sağlayan kullanışlı bir fonksiyondur. ```r select(flights, where(is.numeric)) #sadece sayısal veri tipine sahip sütunları seçecektir select(flights, where(is.character)) #sadece faktör veri tipine sahip sütunları seçecektir ``` .pull-right[.footnote[`int` (integer) ve `dbl` (double) iki `numeric` veri türüdür]] --- ##.left[Diğer `select()` Kullanımları] `select()` fonksiyonunu aynı zamanda sütunların isimlerini ve yerlerini değiştirmek için kullanabiliyoruz ancak bunun için `rename()` ve `relocate()` şeklinde spesifik fonksiyonlar bulunmaktadır. Ancak `select()` sadece ismini değiştirmek istediğimiz sütunu seçecektir, eğer diğer bütün sütunları da seçmek istiyorsak yardımcı `everything()` fonksiyonunu kullanmamız gerekiyor. ```r select(flights, kalkış_gecikme = dep_delay) #sadece kalkış_gecikme sütununu seçecektir select(flights, kalkış_gecikme = dep_delay, everything()) #bütün sütunları seçecektir ``` -- Aynı şekilde `select()` sütunları seçtiğimiz sırayla düzenleyecektir. Bu özelliği sütunların yerini değiştirmek için kullanabiliyoruz. ```r select(flights, carrier, flight, everything()) ``` Yukarıda `carrier` ve `flight` sütunlarını veri çerçevesinin en başına aldık. --- ##.left[Diğer Fonksiyonlara Geçmeden: Pipe (%>%) Operatörü] `dplyr` ve diğer `tidyverse` paketleri [`magrittr`](https://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html) paketinin pipe operatörüyle birlikte çalışacak şekilde tasarlanmışlardır. Pipe operatörünü `%>%` işaretiyle yazıyoruz (Windows kısayolu:`Ctrl+Shift+M`). -- Pipe operatörü *solundaki* nesneyi alarak ona *sağındaki* fonksiyonu uygular: `x %>% f(y) = f(x, y)`. Operatör, "ve sonra" diye okunabilir. Pipe operatörü içeren işlemlerde önce veriseti yazılır, ardından pipe'lar ile fonksiyonlar birbirine eklenir. Böylelikle, bir kez belirtilen veriseti ismi, arkasından gelen fonksiyonların içerisinde tekrar belirtilmez. ```r flights %>% select(-year) %>% view() ``` Yukarıdaki örnekte `flights` veri setini seçtikten *sonra* `year` sütununu kaldırıyor, *sonra da* `view()` fonksiyonuyla veri çerçevesini viewer panosunda inceliyoruz. --- ##.left[Pipe Öperatörünü Kullanmak] Pipe öperatörü daha kolay, okunaklı ve düzenli şekilde kod yazmayı sağlar. Böylece aşağıdaki örnekte olduğu gibi içiçe geçmiş iki fonksiyonu ayırarak daha okunaklı ve kolay şekilde yazabiliriz. ```r head(select(flights, month)) #yerine flights %>% select(month) %>% head() ``` Aynı şekilde birden fazla komut satırıyla yapılacak işlemler tek bir komutla yapılır ```r mydata <- select(flights, -year) mydata <- fct_recode(mydata, air_time > 200) #yerine mydata <- flights %>% select(-year) %>% filter(air_time > 200) ``` **Önemli:** Dersin geri kalanında fonksiyonlar ve paketler uyumlu olduğu sürece kod yazarken *her zaman* pipe operatörünü kullanacağız. --- ##.left[Veri Çerçevelerini filtrelemek: `filter()`] Daha önce base R'da öğe seçerken yaptığımız (örn. `gss_cat[gss_cat$marital == "Married",]`), mantıksal koşullarla öğe seçme işlemlerini `filter()` fonksiyonuyla çok daha kolay ve kullanışlı şekilde yapabiliyoruz. `filter()`, satırlar/gözlemler içerisinde belirtilen mantıksal koşulları karşılaşayan satırları/gözlemleri seçer. ```r flights %>% filter(carrier=="UA") %>% head(n = 5) ``` Yukarıda havayolu şirketi(`carrier`) "UA" olan satırların `head()` ile ilk beş tanesini getirdik. **Not:** Pipe öperatörü içeren kodlar yazılırken, kodu daha okunaklı hale getirmek için genelde her operatörden sonra `Enter` ile bir alt satıra geçilir. --- ##.left[Çoklu Koşullarla Filtreleme] Base R'da öğe seçerken yaptığımız gibi `&`(ve),`|` (veya) ve `!` (değil) operatörüyle birden fazla mantıksal koşulu kombine edebiliriz. Diyelim UA havayolu şirketinin kalkışta ve inişte gecikme yapmayan uçuşlarını bulmak istiyoruz. ```r flights %>% filter(carrier=="UA" & dep_delay==0 & arr_delay==0) %>% head(n = 5) ``` ``` ## # A tibble: 5 × 19 ## year month day dep_time sched_d…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ ## <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> ## 1 2013 1 4 2005 2005 0 2311 2311 0 ## 2 2013 1 6 1932 1932 0 2243 2243 0 ## 3 2013 1 15 745 745 0 922 922 0 ## 4 2013 1 28 1050 1050 0 1340 1340 0 ## 5 2013 1 28 1440 1440 0 1614 1614 0 ## # … with 10 more variables: carrier <chr>, flight <int>, ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, ## # distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>, and ## # abbreviated variable names ¹sched_dep_time, ²dep_delay, ## # ³arr_time, ⁴sched_arr_time, ⁵arr_delay ``` --- ##.left[`%in%` Operatörüyle Filtreleme] Önceki derste gördüğümüz gibi birden fazla eşitlik test ederek seçim yapmak için `%in%` operatörünü kullanıyorduk. ```r flights %>% filter(carrier %in% c("AA", "DL", "EV")) %>% count(carrier, sort = T) ``` ``` ## # A tibble: 3 × 2 ## carrier n ## <chr> <int> ## 1 EV 54173 ## 2 DL 48110 ## 3 AA 32729 ``` `count()` fonksiyonu `fct_count` gibi kategorilerde kaç tane gözlem olduğunu sayar. Ancak `fct_count`dan farklı olarak sadece faktörler için değil karakter verileri gibi farklı veri türleriyle de çalışır. --- ##.left[`between()` Fonksiyonuyla Filtreleme] `between()` fonksiyonu sayısal bir değişkenin/sütunun alt ve üst değerler arasındaki tüm değerlerini seçer. `select()` fonksiyonuyla havayolu şirketi (`carrier`) ve iniş gecikme (`arr_delay`) sütunlarını seçtikten sonra, iniş gecikme süresi 1 dakika ila 60 dakika arasında olan uçuşları seçelim, ilk 5 satıra göz atalım. ```r flights %>% select(carrier, arr_delay) %>% filter(between(arr_delay, 1, 60)) %>% head(5) ``` ``` ## # A tibble: 5 × 2 ## carrier arr_delay ## <chr> <dbl> ## 1 UA 11 ## 2 UA 20 ## 3 AA 33 ## 4 UA 12 ## 5 B6 19 ```