dtplyr Paketi ile Daha Hızlı Veri Manipülasyonu İşlemleri

dplyr Paketi ile Veri Manipülasyonu
R programlama dilinde geliştirilen dplyr paketi ile veri manipülasyonu; bir veri seti hakkında anlamlı bilgilere ulaşmak için satır veya sütun bazında yapılan işlemlerdir. Değişkenler arası dört işlem yapmak, bir veya birden fazla değişken kullanarak yeni bir değişken oluşturmak, kategorik değişkenleri belirli kırılımlarda gruplamak, spesifik gözlemlere ulaşmak gibi işlemler için “dplyr” kütüphanesindeki fonksiyonlar çok kullanışlıdır. dplyr paketi hakkında daha fazla bilgiye ulaşmak için buraya tıklayabilirsiniz. Veri manipülasyonu işlemleri hakkında daha fazla bilgiye ulaşmak için Ekrem Bayar’ın R ile Veri Manipülasyonu: FBI Verisi adlı videosunu inceleyebilirsiniz.

Veri hacmi büyüdükçe, bu veriler üzerinde en basit işlemler bile zaman almaktadır. Büyük veriler üzerinde karmaşık manipülasyon işlemlerinin çok zaman alması problemine çözüm olarak, Hadley Wickham tarafından “dtplyr” adında bir R paketi geliştirilmiştir. “dtplyr” paketi, “dplyr” paketi içerisinde yer alan manipülasyon fonksiyonları ile yapılan işlemleri optimum performansta çalışması için dönüştürmektedir.

Nedir bu optimum performans?
Manipülasyon işlemleri sırasında yazdığımız kodlar, yaptığımız işlemlerin anlaşılabilmesi için, düzenli ve açık bir yapıda olması gerekir. “dtplyr” paketi, yazılan bu düzenli yapıdaki manipülasyon işlemini kendi içerisinde dönüştürerek aynı işlemi minimum sürede uygulayan bir yapıya getirmektedir.

Örneğin aşağıdaki örnek kodlarda yer alan manipülasyon işlemine bakalım.
df %>%
filter(wt < 5) %>%
mutate(l100k = 235.21 / mpg) %>%
group_by(cyl) %>%
summarise(l100k = mean(l100k))


“dtplyr” paketi yukaridaki işlemi kendi anlayabileceği bir yapıya dönüştürüyor. Yani, yukarıdaki işlemin “dtplyr’cası” aşağıda verilen yapıya dönüşüyor. Ve içeride bu fonksiyonu kullanarak istenilen işlemi yapıyor.

[wt < 5][, :=(l100k = 235.21/mpg)][, .(l100k = mean(l100k))keyby = .(cyl)]

Bu şekilde dplyr paketi ile yaptığımız manipülasyon işlemleri 45 kata kadar hızlı çalışabiliyor. Şimdi bu dönüştürme işlemlerini sırasıyla inceleyelim.

Kullanılan Kütüphaneler

devtools::install_github("tidyverse/dtplyr")

library(dplyr, warn.conflicts = FALSE)
library(dtplyr)
library(data.table)
library(readr)

Kullanılan Veri Seti
R’da hazır halde bulunan “mtcars” veri seti kullanılmıştır. 32 satır, 11 sütundan oluşan bu veri setinin bağımlı değişkeni “mpg : miles per galon” sürekli değişkenini tahmin etmek için oluşturulmuş bir veri setidir.

df <- mtcars

1. dplyr Tarzı Veri Manipülasyonu
– filter() fonksiyonu ile “wt” değişkeni 5’ten küçük olanları işleme al,
– mutate() fonksiyonu ile l100k adında bir değişken yarat, l100k değerinin içerisine (235.21/mpg) değerlerini yaz.
– group_by() fonksiyonu ile tüm veriyi “cyl” değişkenine göre grupla,
– summarise() fonksiyonu ile “cyl” değişkenine karşılık gelen l100k değişkeninin ortalamalarını al.

df <- mtcars
df %>% 
  filter(wt < 5) %>% 
  mutate(l100k = 235.21 / mpg) %>% 
  group_by(cyl) %>% 
  summarise(l100k = mean(l100k))

output: 
# A tibble: 3 x 2
#        cyl l100k
#       <dbl> <dbl>
#   1     4  9.05
#   2     6  12.0 
#   3     8  14.9 

2. layz_dt()
Veriyi “lazy” veri tablosu formatına getirerek dplylr kütüphanesinin içerisindeki fonksiyonları kullanılabilir hale getiriyoruz. Verinin tipi “dtplyr_step_first” formatına çevriliyor, yukarıda yaptığımız manipülasyon işlemini bu formattaki veriye uygulayıp optimum çözüme ulaşabiliyoruz.

df_lazy <- lazy_dt(df)
class(df_lazy)

output:
# "dtplyr_step_first" "dtplyr_step" 

3. Optimum Manipülatif Fonksiyonu Bulma İşlemi

df_lazy %>% 
  filter(wt < 5) %>% 
  mutate(l100k = 235.21 / mpg) %>% 
  group_by(cyl) %>% 
  summarise(l100k = mean(l100k))

output:
# Source: local data table [?? x 2]
# Call:   `_DT2`[wt < 5][, `:=`(l100k = 235.21/mpg)][, .(l100k = mean(l100k))keyby = .(cyl)]
# 
#      cyl l100k
#     <dbl> <dbl>
# 1     4   9.05
# 2     6   12.0 
# 3     8   14.9 

# Use as.data.table()/as.data.frame()/as_tibble() to access results

Çıktıda yer alan “Call” nesnesinin içerisindeki fonksiyona bakınız. İşte bu fonksiyon, 1. bölümde yapılan manipülasyon işlemini en hızlı çalıştıran fonksiyondur.

_DT2 ifadesini data.table formatındaki veri setini ifade etmektedir. Bir sonraki bölümde, ham veriyi data.table formatına getirerek dtplyr işlemini manuel olarak uygulayacağız.

4. “dtplyr” ile Oluşturulan Fonksiyonun Manuel Uygulaması

df_datatable <- as.data.table(df)
df_datatable[wt < 5][, `:=`(l100k = 235.21/mpg)][, .(l100k = mean(l100k)), 
                                     keyby = .(cyl)]

output:
#     cyl     l100k
# 1:   4     9.048898
# 2:   6     11.970180
# 3:   8     14.871885

data.table() olarak kaydettiğimiz ham verinin adını, 3. bölümde yer alan Call nesnesinin içerisindeki _DT2’nin yerine yazıyoruz.
Sonuç olarak, df değişkenine atanan ham veriyi data.table() olarak kaydettiğimizde dtplyr’ın bize sunduğu optimum işlemi uygulayabildik.

5. dtplyr ile Yaratılan Fonksiyonun Otomatik Olarak Uygulanması
Ara işlemlere gerek duymadan, bu işlemi direkt olarak uygulayıp hızlıca sonuç almak için aşağıdaki işlem sırasını tahip edebilirsiniz. Burayı diğerlerinden ayıran

df <- mtcars
df_lazy <- lazy_dt(df)

df_lazy %>% 
  filter(wt < 5) %>% 
  mutate(l100k = 235.21 / mpg) %>% 
  group_by(cyl) %>% 
  summarise(l100k = mean(l100k)) %>% as.data.frame()

output:
#     cyl     l100k
# 1:   4     9.048898
# 2:   6     11.970180
# 3:   8     14.871885

Genel olarak veri setinin lazy_dt() ile formatını değiştirdikten sonra, dplyr tarzı veri manipülasyon işlemini yapıyoruz ve son olarak da sonucu tibble, data.frame veya data.table formatında saklıyoruz.

Uygulama
Bu işlemi büyük bir veri setinde uygulayarak performans karşılaştırması yapacağız. Kullanılan veri setine kaggle ‘dan ulaşabilirsiniz.

1. Veri Okuma İşlemi

flight_delays <- readr::read_csv("flights.csv")
df <- flight_delays

2. Standart dplyr

start_time <- Sys.time()
df_delay <- df %>% 
  group_by(DESTINATION_AIRPORT) %>% 
  summarise(AvgDelay = mean(ARRIVAL_DELAY)) %>% 
  arrange(DESTINATION_AIRPORT, desc(AvgDelay)) %>% as_tibble()
end_time <- Sys.time()
time <- end_time - start_time
time

output:
# Time difference of 0.9610851 secs

Yukarıda yaptığımız standart dplyr işlemi 0.96 saniye sürmüştür.

3. lazy_dt() Formatına Çevirme İşlemi

df_delay_lazy <- lazy_dt(df)

4. dtplyr Tarzı Manipülasyon

start_time_lazy <- Sys.time()
df_delay_dtply <- df_delay_lazy %>% 
  group_by(DESTINATION_AIRPORT) %>% 
  summarise(AvgDelay = mean(ARRIVAL_DELAY)) %>% 
  arrange(DESTINATION_AIRPORT, desc(AvgDelay)) %>% as_tibble()
end_time_lazy <- Sys.time()
time_lazy <- end_time_lazy - start_time_lazy
time_lazy

output:
Time difference of 0.1476011 secs

Yukarıda yaptığımız dtplyr formatındaki manipülasyon işlemi 0.14 saniye sürmüştür.

5. dplyr vs. dtplyr

list("dplyr" = time, "dtplyr" = time_lazy) 

output: 
# $dplyr
# Time difference of 0.9610851 secs
# 
# $dtplyr
# Time difference of 0.1476011 secs

Bazı manipülasyon işlemlerinde dtplyr ile yapılan manipülasyon işlemlerinin dplyr standart fonksiyonlarına göre performansı 45 kata kadar çıkmaktadır. Veri büyüdükçe veya yaptığınız manipülasyon işlemleri karmaşıklaştıkça bu tip yöntemler zaman ve performans açısından çok yararlı olacaktır.

Sonuç olarak, “dplyr” ile yaptığımız manipülasyon işlemlerini, daha kısa sürede yapabilmek için, “dtplyr” paketinden yararlandık. Kullanmış olduğumuz paket, henüz ilk versiyonunda olduğu için yaptığımız işlem sadece iki yöntemi zaman açısından kıyaslamak oldu. Paketin yeni versiyonları geldikçe bu konu üzerinde daha çok ve çeşitli bilgiler vereceğim.

Değerli zamanınızı ayırdığınız için teşekkürler.

Yazar Hakkında
Toplam 13 yazı
Mustafa Nayansak
Mustafa Nayansak
Yorumlar (Yorum yapılmamış)

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

×

Bir Şeyler Ara