class: center, top, title-slide .title[ # İLT668, Dördüncü Ders ] .subtitle[ ## Tidyverse Paketleriyle Veri Manipülasyonu II: Arrange, Relocate, Rename, Mutate ] .author[ ### Umut Yener Kara ] .date[ ### 19 Mart, 2023
Güncelleme: Mar 26, 2023 ] --- class: inverse #.left[Tidyverse ile Veri Manipülasyonu II] * `arrange()` * `relocate()` * `rename()` * `mutate()`,`ifelse()`,`case_when()` * `group_by()`ve `summarize` --- ##.left[Sıralama: `arrange()`] `arrange()` fonksiyonu, bir veri setindeki satırların/gözlemlerin sıralamasını değiştirir. Sıralama, birden fazla sütun baz alınarak da yapılabilir. Bu tip durumlarda, önce ilk değişken sıralanır, ardından ise, ilk sütunun her bir seviyesine karşılık gelen ikinci değişkenler kendi içerisinde sıralanır. ```r flights %>% select(month, day, carrier) %>% arrange(month, desc(day)) %>% head(5) ``` ``` ## # A tibble: 5 × 3 ## month day carrier ## <int> <int> <chr> ## 1 1 31 WN ## 2 1 31 B6 ## 3 1 31 B6 ## 4 1 31 B6 ## 5 1 31 B6 ``` Veriler ay(`month`) değişkeni için küçükten büyüğe, gün(`day`) değişkeni için ise büyükten küçüğe sıralandı. --- ##.left[Karakter Değerlerini Sıralamak] `arrange()` fonksiyonu sadece sayısal değişkenlerin içerisindeki değerleri değil karakter değişkenleri içerisindeki değerleri sıralamak için de kullanılabilir. Böyle olduğunda satırlar alfabeye göre sıralanacaklardır. ```r flights %>% select(tailnum, carrier) %>% arrange(tailnum) %>% head(10) ``` ``` ## # A tibble: 10 × 2 ## tailnum carrier ## <chr> <chr> ## 1 D942DN DL ## 2 D942DN DL ## 3 D942DN DL ## 4 D942DN DL ## 5 N0EGMQ MQ ## 6 N0EGMQ MQ ## 7 N0EGMQ MQ ## 8 N0EGMQ MQ ## 9 N0EGMQ MQ ## 10 N0EGMQ MQ ``` --- ##.left[Sütunların Yerlerini Değiştirmek: `relocate()`] `relocate()` sütunların yerini değiştirmenin `select()` fonksiyonuna göre daha kolay ve esnek yollarını sağlar. ```r flights %>% relocate(carrier, time_hour) ``` `carrier` ve `time_hour` sütunlarını en başa aldık. ```r flights %>% relocate(hour, minute, .before = day) ``` `.before` argümanıyla `hour` ve `minute` sütunlarını `day` sütununun öncesine aldık. ```r flights %>% relocate(year, .after = last_col()) ``` `year` sütununu en sona aldık. --- ##.left[Sütunların İsmini Değiştirmek: `rename()`] **`rename()`** `select()` ile aynı şekilde sütunların ismini değiştirmek için kullanılır (rename(yeni isim = eski isim) şeklinde). Ancak `select`den farklı olarak seçilen sütunlar haricindekileri veri setinden silmez. ```r flights %>% rename(yıl = year, ay = month, gün = day) %>% head(4) ``` ``` ## # A tibble: 4 × 19 ## yıl ay gün dep_time sched_d…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ ## <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> ## 1 2013 1 1 517 515 2 830 819 11 ## 2 2013 1 1 533 529 4 850 830 20 ## 3 2013 1 1 542 540 2 923 850 33 ## 4 2013 1 1 544 545 -1 1004 1022 -18 ## # … 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 ``` --- class:inverse #.left[Değişkenler Yaratmak] --- ##.left[`mutate()`] **`mutate()`** fonksiyonu veri çerçevelerine yeni değişkenler eklemek veya eskilerini değiştirmek için kullanılır. Yeni değişkenler her zaman tablonun en sonuna (sağına) eklenir. Yeni değişkenler yaratırken, fonksiyonlar, aritmetik, ilişkisel veya mantıksal operatörler kullanılabilir. Diyelim uçakların havada uçuş süresi olan `air_time` değişkenini saate dönüştürerek `air_time_hour` isimli yeni bir sütun yaratmak ve yeni bir veri setine kaydetmek istiyoruz. ```r flights_new <- flights %>% mutate(air_time_hour = air_time / 60) ``` Virgül (`,`) işaretiyle birden fazla yeni değişken de yaratabiliriz. ```r flights %>% mutate(air_time_hour = air_time / 60, dep_delay_hour = dep_delay / 60, arr_delay_hour = arr_delay / 60) ``` **Not:**Birden fazla değişkene aynı işlemi uygulayarak yeni değişkenler yaratmak için daha kısa - ama zor ve karışık - bir yol `mutate` içerisinde `across()` fonksiyonunu kullanmaktır. Yukarıdaki işlemin aynısı: `flights %>% mutate(across(c(air_time,dep_delay, arr_delay), ~ ./60, .names = "{.col}_hour"))` --- ##.left[Daha Karmaşık Bir `mutate()` Örneği] Diyelim her bir uçağın hızını hesaplayarak "hız" isimli yeni bir değişken oluşturmak istiyoruz. Hız formülü: `Hız = yol (distance) / zaman (air_time)` Ancak bu formülle dakikada kaç mil hızla gittiğini bulduğumuzdan değeri 60'la çarpıp önce saate, sonrasında ise mili 1.603 değeriyle çarparak km'ye çevirmemiz gerekiyor. Tam formül: `Hız(km) = yol (distance) / zaman (air_time) * 60 * 1.603` ```r flights %>% mutate(hız=(distance/air_time) * 60 * 1.603) %>% select(distance, air_time, hız) %>% arrange(-hız) %>% head(5) ``` ``` ## # A tibble: 5 × 3 ## distance air_time hız ## <dbl> <dbl> <dbl> ## 1 762 65 1128. ## 2 1008 93 1042. ## 3 594 55 1039. ## 4 748 70 1028. ## 5 1035 105 948. ``` --- ##.left[`ifelse()`] `mutate()` içerisinde sıkça kullanılan bir fonksiyon `ifelse()`'dir. Fonksiyon ilk argümanda belirtilen mantıksal koşulu test eder. Eğer test sonucu TRUE ise ikinci argümanı getirir. Eğer FALSE ise üçüncüsünü getirir. Basit bir örnek: ```r x <- 10 ifelse(x > 9, "x is greater than 9", "x is not greater than 9") ``` ``` ## [1] "x is greater than 9" ``` Fonksiyonu `mutate()` içerisinde kullanarak `gecikme_durumu` diye bir sütun yaratalım, kalkış gecikmesi (`dep_delay`) 0'dan büyük uçuşları "rötarlı", 0 veya küçük olanları ise "rötarsız" diye sınıflandıralım. ```r flights %>% mutate(rötar_durumu = ifelse(dep_delay > 0, "rötarlı", "rötarsız")) ``` --- ##.left[`case_when()`] `ifelse()` ile sadece tek bir mantıksal koşul test ederken, `case_when()` ile birden fazla mantıksal koşul test edebiliyoruz. Yukarıda yaptığımızı daha ayrıntılı yaparak, kalkış gecikmesi (`dep_delay`) -1,-10 arasındaki uçuşları "az_erken", -10'dan küçükleri "çok_erken; 1, 10 dakika arası gecikme yaşan uçuşları "az_gecikme", 10 dakikadan fazla gecikme yaşayan uçuşları ise "çok_gecikme" diye sınıflandıralım. Kalkış gecikmesi 0 olanlar ise "zamanında" olsun. ```r flights %>% mutate(gecikme_durumu = case_when(between(dep_delay, -1,-10) ~ "az_erken", dep_delay < -10 ~ "çok_erken", between(dep_delay, 1,10) ~ "az_gecikme", dep_delay > 10 ~ "çok_gecikme", TRUE ~ "zamanında")) %>% count(gecikme_durumu, sort = T) ``` ``` ## # A tibble: 4 × 2 ## gecikme_durumu n ## <chr> <int> ## 1 zamanında 201766 ## 2 çok_gecikme 82834 ## 3 az_gecikme 45598 ## 4 çok_erken 6578 ``` --- class: inverse # Verileri Özetlemek --- ## Genel Özetler: `summarize()` **summarize()** veya **summarise()** sütunlardaki değerlerin tamamını özetleyen hesaplamalar yapmak için kullanılır. Başta aşağıdakileri hesaplamak için kullanılır: * Toplam satır sayısı * Ortalama * Toplamlar * Minimum ve maksimum değerler **summarize()** her zaman özet değerlerden oluşan ayrı bir veri çerçevesi yaratır. `summarize()` içerisinde *çoğul değerleri* *tek değer* halinde derleyen (aggregate) her türlü fonksiyon kullanılabilir (örn. `sd()`, `mean()`, veya `max()`) --- ## `summarize()` Örneği Flights veri setinde Ocak ayındaki uçuşlar için `toplam gözlem sayısı`, `minimum gecikme`, `ortalama kalkış gecikmesi` ve `medyan gecikme` değerlerini hesaplayalım. ```r flights %>% filter(month == 1) %>% summarize(gözlem_sayısı = n(), min_gecikme = min(dep_delay, na.rm = T), ortalama_gecikme = mean(dep_delay, na.rm = T), medyan_gecikme = median(dep_delay, na.rm = T)) ``` ``` ## # A tibble: 1 × 4 ## gözlem_sayısı min_gecikme ortalama_gecikme medyan_gecikme ## <int> <dbl> <dbl> <dbl> ## 1 27004 -30 10.0 -2 ``` Ancak aynı şeyi ve daha fazlasını `summary()`fonksiyonu ile çok daha kolay bir şekilde yapabilirdik. O halde neden `summarize()` fonksiyonunu kullanıyoruz? --- ## `group_by` Fonksiyonları `group_by()` fonksiyonu izleyen fonksiyonların verileri işleme biçimini değiştirir ve genellikle `summarize()` ile birlikte kullanılır. `group_by()` ile `summarize()` birden çok grubun ve kategorinin özetlerini çıkartmak için kullanılır. `group_by()` fonksiyonunu izleyen fonksiyonlar *her grup için* hesaplanır. Diğer değişle bir sütundaki bütün değerler için değil, her eşsiz değer için *ayrı ayrı* hesaplanır. Genelde gruplandırılan değişkenler tam sayı, faktör veya karakter tipi veriler olacaktır, *sürekli değerler* değil. --- ## `group_by()` Örneği I Diyelim tüm uçuşların kalkarken gecikme zamanı ortalaması yerine, her bir havayolu şirketinin uçuşlarının kalkarken gecikme zamanı ortalamasını nasıl çıkarabiliriz? Burada grup, havayolu şirketleri (carrier), özet ise onların kalkış gecikme zamanı (dep_delay) ortalama değeridir: ```r flights %>% group_by(carrier) %>% summarize(gecikme_ort = mean(dep_delay, na.rm=TRUE)) %>% arrange(-gecikme_ort) %>% head(10) ``` ``` ## # A tibble: 10 × 2 ## carrier gecikme_ort ## <chr> <dbl> ## 1 F9 20.2 ## 2 EV 20.0 ## 3 YV 19.0 ## 4 FL 18.7 ## 5 WN 17.7 ## 6 9E 16.7 ## 7 B6 13.0 ## 8 VX 12.9 ## 9 OO 12.6 ## 10 UA 12.1 ``` --- ## `group_by()` Örneği II Diyelim hangi havayolunun kaç uçuş yaptığını sayı ve yüzdelik oran halinde görmek istiyoruz. ```r flights %>% group_by(carrier) %>% summarize(uçuş_sayısı = n(), yüzdelik_oran = n()/nrow(flights) * 100) %>% arrange(-uçuş_sayısı) %>% head(10) ``` ``` ## # A tibble: 10 × 3 ## carrier uçuş_sayısı yüzdelik_oran ## <chr> <int> <dbl> ## 1 UA 58665 17.4 ## 2 B6 54635 16.2 ## 3 EV 54173 16.1 ## 4 DL 48110 14.3 ## 5 AA 32729 9.72 ## 6 MQ 26397 7.84 ## 7 US 20536 6.10 ## 8 9E 18460 5.48 ## 9 WN 12275 3.64 ## 10 VX 5162 1.53 ``` --- ## Birden fazla değişkenle `group_by()` Analizlerimizde veriyi sadece tek bir değişkenin değerlerine göre gruplandırmak yerine birden fazla değişkenin değerlerine göre de gruplandırabiliyoruz. Örneğin en fazla hangi uçuş rotasının kullandığını bulalım. ```r flights %>% group_by(origin, dest) %>% summarize(toplam_sayı = n(), yüzdelik_oran = n()/nrow(flights) * 100, .groups = "drop") %>% arrange(-toplam_sayı) ``` ``` ## # A tibble: 224 × 4 ## origin dest toplam_sayı yüzdelik_oran ## <chr> <chr> <int> <dbl> ## 1 JFK LAX 11262 3.34 ## 2 LGA ATL 10263 3.05 ## 3 LGA ORD 8857 2.63 ## 4 JFK SFO 8204 2.44 ## 5 LGA CLT 6168 1.83 ## 6 EWR ORD 6100 1.81 ## 7 JFK BOS 5898 1.75 ## 8 LGA MIA 5781 1.72 ## 9 JFK MCO 5464 1.62 ## 10 EWR BOS 5327 1.58 ## # … with 214 more rows ```