Özet

Bu dökümanın amacı en azından temel bilgisayar kabiliyetlerine1 sahip olan kişileri olabilecek en hızlı bir şekilde R ile veri analizinde bir şeyler oluşturabilecek seviyeye getirebilmektir.

Bu amaca ulaşabilmek için kurulumu minimal düzeyde tutmaya çalıştım. R, RStudio ve analizlerin R içerisinden raporlanabilmesi için (diğer bir deyişle RMarkdown kullanabilmek için) Pandoc kurulumlarını önereceğim. Analizleri yapmak için aslen sadece R yeterli olsa da RStudio kod yazmayı kolaylaştırmak için; RMarkdown da bir başka zorlu süreç olan analizleri raporlayabilmek için önemli unsurlar.

Bu kısa çalışmada çok spesifik bir veri seti üzerinde işler yapacağız; sandık bazında genel seçim verileri. İki adet veri setimiz bulunuyor: 7 Haziran 2015 ve 1 Kasım 2015 Türkiye Milletvekili Seçimi sandık bazında seçim sonuçları. Bu veri setlerini ise GitHub üzerinden oluşturduğum secimler paketinden alacağız.

Kullanacağımız yöntem ise benzersiz. R’ın temellerini veya adım adım kullanımını atlayarak doğrudan basit analizler için ihtiyacımız olan en rahat araçlara yöneleceğiz. Bu araçlar tidyverse adlı bir paketin içinde yer alan paketler. Kullanacağımız başlıca paketler ise dplyr (veri manipülasyonu için) ve ggplot2 (grafikler için).

Bunu güzel bir diziyi izlemeye sıkıcı ilk iki sezonunu atlayarak üçüncü sezonundan başlamakla karşılaştırabiliriz. Temel fonksiyonlara ihtiyaç duyduğumuzda flashbackler yaşayacağız ve olay örgüsünün geçmişini ve karakter gelişimini görmek için ilk iki sezonu izlememiz gerekebilir ama keyif almak için üçüncü sezondan başlamanın hiçbir zararı yok. Zira R, 3. sezondan sonra güzelleşen bir programlama dili.

Sorunuz yoksa başlıyoruz. Varsa, bana yazın.

Kurulum Hazırlığı

Üç program kurmamız gerekiyor.

İlk Adımlar

Aşağıdaki kodları çalıştırmak için RStudio’nun konsoluna kopyala yapıştır yapmamız gerekiyor. Veya RStudio’da açtığınız yeni bir R dosyasına kopyala yapıştır yapıp satırları oradan da çalıştırabilirsiniz. (Ufak not # ile başlayan satırlar comment ya da yorum olarak adlandırılırlar. R bunları çalıştırmaz. Genelde yorumlara ilgili kodların ne işe yaradığına dair açıklayıcı notlar yazılır.)

#Bu kodlar sadece bazı genel ayarları içeriyor
#Veri alırken string formatındaki sütunları faktör gibi görme
options(stringsAsFactors=FALSE)
#Paketleri bu adresten yükle
options(repos="http://cran.rstudio.com/")
#Veri tablolarının bütün sütunlarını göster
options(dplyr.width = Inf)
#Ondalık veri gösterme formatı ile ilgili bir ayar
options(scipen = 7)

Sırada ihtiyaç duyduğumuz paketleri yükleyeceğiz.

#devtools R'ın kendi paket sistemi dışında paketleri kurabilmemize yardımcı olacak.
install.packages("devtools")
#tidyverse R içerisinde kullanacağımız özel komutları içeren paketler grubu
install.packages("tidyverse")
#secimler paketini R'ın kendi sistemi içerisinden değil GitHub denilen bir kod depo
#sistemi üzerinden yükleyeceğiz.
#Bu paket kullanacağımız verileri içeriyor
devtools::install_github("berkorbay/secimler")

Yukarıdaki install.packages kodu bir paket deposundan ilgili paketleri indirmeyi sağlamaktadır. install_github ise GitHub’da bulunan paketi indirmeye yarıyor. Komutun devtools::install_github şeklinde yazılmasının nedeni ise devtools paketini “yüklemeye” gerek kalmadan R’a spesifik olarak o paketin içinden bir komutu çağırmasını istememizdir.

Paketleri indirmek ile çalıştırmak (veya yüklemek) farklı fonksiyonlar gerektirmektedir. Yüklemek için library komutunu kullanıyoruz.

#Şimdi indirdiğimiz paketleri yükleyelim
library(tidyverse)
library(secimler)

Hazırlıklarımız tamamlandı. Uçuşa geçebiliriz :)

R ve dplyr ile Veri Analizi

Önce verilerimizi tanıyalım. secimler paketi iki veri seti içeriyor. Bunlar, 7 Haziran 2015 genel seçim sonuçlarını içeren secim150607g isimli veri seti ve 1 Kasım 2015 genel seçim sonuçlarını içeren secim151101g isimli veri setidir. Veri setlerinin ikisi de format olarak aynıdır, ancak doğal olarak içerikleri farklıdır. Haziran sonuçlarına bir göz atalım.

head(secim150607g)
## # A tibble: 6 × 30
##      il bolge   ilce               cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl>  <chr>               <chr>      <chr>  <dbl>          <dbl>
## 1 Adana     1    İli               Genel     Toplam   4426        1477328
## 2 Adana     1    İli       İl-İlçe Genel     Toplam   4426        1477328
## 3 Adana     1 Seyhan               Genel     Toplam   1473         529658
## 4 Adana     1 Seyhan       İl-İlçe Genel     Toplam   1473         529658
## 5 Adana     1 Seyhan Ahmet Remzi Yüreğir    Mahalle   3001            341
## 6 Adana     1 Seyhan Ahmet Remzi Yüreğir    Mahalle   3002            339
##   oy_kullanan gecerli_oy ak_parti    chp    mhp    hdp   dyp
##         <dbl>      <dbl>    <dbl>  <dbl>  <dbl>  <dbl> <dbl>
## 1     1254393    1229817   368055 354389 287799 177730  1100
## 2     1254393    1229817   368055 354389 287799 177730  1100
## 3      449743     441384   113966 138646  79714  94887   435
## 4      449743     441384   113966 138646  79714  94887   435
## 5         285        279      111     49     81     29     0
## 6         278        270       98     59     66     35     0
##   anadolu_partisi hak_par    kp millet_partisi   hap   mep turk_parti
##             <dbl>   <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl>
## 1             590    1265   310            509     0   644       2199
## 2             590    1265   310            509     0   644       2199
## 3             227     379   120            133     0   170        545
## 4             227     379   120            133     0   170        545
## 5               0       0     0              0     0     1          1
## 6               0       0     0              0     0     0          0
##     hkp   ldp saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp
##   <dbl> <dbl>          <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>
## 1  1432   967          18917  1897          0  1534          3731  1735
## 2  1432   967          18917  1897          0  1534          3731  1735
## 3   408   288           6605   643          0   383          1284   607
## 4   408   288           6605   643          0   383          1284   607
## 5     0     0              0     0          0     0             2     0
## 6     0     1              3     0          0     0             0     0
##   bagimsiz
##      <dbl>
## 1     5014
## 2     5014
## 3     1944
## 4     1944
## 5        5
## 6        8
glimpse(secim150607g)
## Observations: 176,831
## Variables: 30
## $ il              <chr> "Adana", "Adana", "Adana", "Adana", "Adana", "...
## $ bolge           <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
## $ ilce            <chr> "İli", "İli", "Seyhan", "Seyhan", "Seyhan", "S...
## $ cevre           <chr> "Genel", "İl-İlçe Genel", "Genel", "İl-İlçe Ge...
## $ cevre_turu      <chr> "Toplam", "Toplam", "Toplam", "Toplam", "Mahal...
## $ sandik          <dbl> 4426, 4426, 1473, 1473, 3001, 3002, 3003, 2001...
## $ kayitli_secmen  <dbl> 1477328, 1477328, 529658, 529658, 341, 339, 34...
## $ oy_kullanan     <dbl> 1254393, 1254393, 449743, 449743, 285, 278, 29...
## $ gecerli_oy      <dbl> 1229817, 1229817, 441384, 441384, 279, 270, 28...
## $ ak_parti        <dbl> 368055, 368055, 113966, 113966, 111, 98, 88, 1...
## $ chp             <dbl> 354389, 354389, 138646, 138646, 49, 59, 67, 28...
## $ mhp             <dbl> 287799, 287799, 79714, 79714, 81, 66, 81, 4, 4...
## $ hdp             <dbl> 177730, 177730, 94887, 94887, 29, 35, 49, 9, 5...
## $ dyp             <dbl> 1100, 1100, 435, 435, 0, 0, 0, 1, 0, 0, 0, 0, ...
## $ anadolu_partisi <dbl> 590, 590, 227, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ hak_par         <dbl> 1265, 1265, 379, 379, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ kp              <dbl> 310, 310, 120, 120, 0, 0, 0, 0, 1, 0, 0, 2, 0,...
## $ millet_partisi  <dbl> 509, 509, 133, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ hap             <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## $ mep             <dbl> 644, 644, 170, 170, 1, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ turk_parti      <dbl> 2199, 2199, 545, 545, 1, 0, 0, 0, 0, 1, 0, 0, ...
## $ hkp             <dbl> 1432, 1432, 408, 408, 0, 0, 0, 0, 0, 0, 1, 0, ...
## $ ldp             <dbl> 967, 967, 288, 288, 0, 1, 0, 0, 1, 0, 0, 0, 0,...
## $ saadet_partisi  <dbl> 18917, 18917, 6605, 6605, 0, 3, 1, 1, 2, 1, 5,...
## $ dsp             <dbl> 1897, 1897, 643, 643, 0, 0, 0, 0, 0, 0, 0, 1, ...
## $ yurt_parti      <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## $ dp              <dbl> 1534, 1534, 383, 383, 0, 0, 0, 0, 0, 1, 0, 0, ...
## $ vatan_partisi   <dbl> 3731, 3731, 1284, 1284, 2, 0, 0, 2, 0, 0, 0, 2...
## $ btp             <dbl> 1735, 1735, 607, 607, 0, 0, 0, 0, 0, 1, 0, 0, ...
## $ bagimsiz        <dbl> 5014, 5014, 1944, 1944, 5, 8, 2, 0, 1, 0, 0, 0...

Seçim verileri data frame denilen bir formatın türevi olan tbl_df veya `tibble formatı ile tutulmaktadırlar (veri yapıları temel R konuları içerisinde yer alıyor şimdilik çok önemli değil direk data frame diyebiliriz). head komutu bir veri setinin ilk birkaç satırını gösterir. glimpse komutu ise bir data frame’in sütunlarını listeler, türlerini belirtir ve birkaç veri örneği verir.

Eğer veri setleri veya komutlar hakkında detaylı bilgi almak istiyorsanız konsolda ilgili komutun başına ? yazıp çalıştırırsanız yardım dosyaları çıkacaktır. Mesela ?secim150607g veya ?head ilgili konularda yardım dosyalarını açar. Yardım dosyaları genellikle R kodlarının işlevlerini anlamada ve hatırlamada çok yardımcı olurlar. Bu veri setlerinde her bir satır ya bir sandığın bilgisini ya da ilgili bölgenin toplam verilerini içerirler.

R’da bir değişkene atama <- veya = ile yapılır. Mesela x değişkenine 5 değerini atamak isterseniz x<-5 yazarsınız. Biz de 7 Haziran seçim veri setini secim_data değişkenine atayalım.

secim_data <- secim150607g
head(secim_data)
## # A tibble: 6 × 30
##      il bolge   ilce               cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl>  <chr>               <chr>      <chr>  <dbl>          <dbl>
## 1 Adana     1    İli               Genel     Toplam   4426        1477328
## 2 Adana     1    İli       İl-İlçe Genel     Toplam   4426        1477328
## 3 Adana     1 Seyhan               Genel     Toplam   1473         529658
## 4 Adana     1 Seyhan       İl-İlçe Genel     Toplam   1473         529658
## 5 Adana     1 Seyhan Ahmet Remzi Yüreğir    Mahalle   3001            341
## 6 Adana     1 Seyhan Ahmet Remzi Yüreğir    Mahalle   3002            339
##   oy_kullanan gecerli_oy ak_parti    chp    mhp    hdp   dyp
##         <dbl>      <dbl>    <dbl>  <dbl>  <dbl>  <dbl> <dbl>
## 1     1254393    1229817   368055 354389 287799 177730  1100
## 2     1254393    1229817   368055 354389 287799 177730  1100
## 3      449743     441384   113966 138646  79714  94887   435
## 4      449743     441384   113966 138646  79714  94887   435
## 5         285        279      111     49     81     29     0
## 6         278        270       98     59     66     35     0
##   anadolu_partisi hak_par    kp millet_partisi   hap   mep turk_parti
##             <dbl>   <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl>
## 1             590    1265   310            509     0   644       2199
## 2             590    1265   310            509     0   644       2199
## 3             227     379   120            133     0   170        545
## 4             227     379   120            133     0   170        545
## 5               0       0     0              0     0     1          1
## 6               0       0     0              0     0     0          0
##     hkp   ldp saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp
##   <dbl> <dbl>          <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>
## 1  1432   967          18917  1897          0  1534          3731  1735
## 2  1432   967          18917  1897          0  1534          3731  1735
## 3   408   288           6605   643          0   383          1284   607
## 4   408   288           6605   643          0   383          1284   607
## 5     0     0              0     0          0     0             2     0
## 6     0     1              3     0          0     0             0     0
##   bagimsiz
##      <dbl>
## 1     5014
## 2     5014
## 3     1944
## 4     1944
## 5        5
## 6        8

İlk komutlarınızı çok güzel çalıştırdınız, tebrik ederim! Şimdi biraz da işlem yapalım. dplyr paketinde hayatınızı çok kolaylaştıracak basit 5-6 komut ve türevleri bulunuyor. Bunların teker teker üzerinden geçeceğiz ve bitirdiğimizde R’ı neredeyse Excel işlevinde kullanabileceksiniz.

dplyr::filter

filter, adından da kolaylıkla anlaşılabileceği gibi veriyi belli kriterlere göre filtrelemeye yarıyor. Örneğin bizim seçim veri setimizden sadece Uşak iline ait verileri almak istediğimizi düşünelim. Ayrıca seçim verisi satırladında bazı satırlar il/ilçe/köy toplamlarını da içeriyor ve sadece düz sandık verisini istiyoruz. O zaman aşağıdaki gibi bir kod yazıyoruz.

#Yeni değişkenimizin adı usak_data olsun
usak_data <-
#secim_data değişkenini al
secim_data %>%
#filtrele
#il Uşak olsun, toplam değerlerini de at
filter(il == "Uşak" & cevre_turu != "Toplam")

#Bana veriyi göster
head(usak_data)
## # A tibble: 6 × 30
##      il bolge  ilce      cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001            312
## 2  Uşak     1 Banaz Cumhuriyet    Mahalle   1002            313
## 3  Uşak     1 Banaz Cumhuriyet    Mahalle   1003            311
## 4  Uşak     1 Banaz Cumhuriyet    Mahalle   1004            313
## 5  Uşak     1 Banaz Cumhuriyet    Mahalle   1005            316
## 6  Uşak     1 Banaz Cumhuriyet    Mahalle   1006            313
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp   dyp anadolu_partisi
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>           <dbl>
## 1         265        258       86    95    63     9     0               1
## 2         262        253       75    85    79     0     0               0
## 3         265        259       77    68   104     6     0               0
## 4         270        264       57    85   117     0     0               0
## 5         275        268       96    85    79     3     0               0
## 6         273        270       88    84    87     3     0               0
##   hak_par    kp millet_partisi   hap   mep turk_parti   hkp   ldp
##     <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl> <dbl> <dbl>
## 1       0     0              0     0     0          0     3     0
## 2       0     0              0     0     0          0     0     0
## 3       0     0              0     0     0          0     1     0
## 4       0     0              0     0     0          0     0     0
## 5       0     0              0     0     0          0     0     0
## 6       0     0              0     0     0          0     0     0
##   saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp bagimsiz
##            <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>    <dbl>
## 1              0     1          0     0             0     0        0
## 2              9     1          0     0             3     1        0
## 3              0     0          0     0             2     1        0
## 4              3     1          0     1             0     0        0
## 5              3     0          0     0             1     1        0
## 6              5     0          0     0             2     1        0

Size ilk başta yabancı gelebilecek ama alıştıktan sonra büyük rahatlık sağlayacak ilk unsur %>%. Bu ifadenin adı “pipe operator” ama dilimize boru operatörü yerine zincir operatörü demek daha hoş geldiği için zincir operatörü diyeceğim. Bu operatör dplyr komutlarını arka arkaya değişken adını tekrar yazmamıza gerek kalmayacak şekilde sıralamamızı ve dolayısıyla daha okunabilir bir kod yazmamızı sağlıyor. Kısaca aynı değişken üzerinde yapılacak işlem sırasını düzenliyor.

== ve != operatörleri ise eşittir ve eşit değildir kontrollerini yapıyorlar. Bunların dışında büyüktür ve büyük eşittiri içeren > ve >=; veya küçüktür ve küçük eşittiri içeren operatörler olan < ve <= de kullanilabilirler. & operatörü ise koşulları birbirlerine bağlamaya yarayan “ve” anlamına gelen operatör. Veya anlamına gelen operatörün sembolü ise | şeklinde (l harfi değil klavyedeki uzun dik çizgi). Yukarıdaki örnekte satırların il değeri Uşak olsun VE cevre_turu değeri Toplam olmasın demiştik, böylece R sadece iki koşulu birlikte sağlayan satırları bize vermiş oldu. (Bu konseptlere çok aşina değilseniz birkaç egzersiz yapabilirsiniz.)

Eğer zincir operatörü veya dplyr olmasaydı aynı sonucu şu şekilde alabilecektik. Aynı değişken ismini kaç kez tekrar ettiğimize dikkat edin. Zincir operatörünün değeri komut sayısı arttıkça daha da çok belli olacak.

head(secim_data[secim_data$il == "Uşak" & secim_data$cevre_turu != "Toplam",])

dplyr’ın ilk komutunu tamamladık. Sırada select ve türevi rename bulunuyor.

Not: Uşak’ı seçme sebeplerim arasında hem ilçeleri hem de köy/beldeleri olması, yeterince küçük ve yeterince büyük olması yatıyor. Ha bir de zamanında CHP Uşak milletvekili danışmanıydım :) Osman Coşkunoğlu’nun yazılarını mutlaka okumalısınız. Bilişim, teknoloji, son zamanlarda endüstri 4.0 ve ilgili politikalar hakkında yazıyor (tıklayın). Ayrıca en sevdiğim köy ismi (Gökçukur) de Uşak’ta.

dplyr::select/rename

select anlatması en kolay komutlardan bir tanesi. Sadece istediğiniz sütunları seçip diğer sütunları atmanızı sağlıyor. Örneğin diyelim oy verileri değil sadece sandık verilerini (il, ilçe, seçim çevresi, çevre türü, sandık no, kayıtlı seçmen ve geçerli oy) istiyoruz. Hepsini select komutunun içine yazarak sadece o sütunları alabiliyoruz.

usak_data %>%
select(il,ilce,cevre,cevre_turu,sandik,kayitli_secmen,oy_kullanan) %>%
slice(1)
## # A tibble: 1 × 7
##      il  ilce      cevre cevre_turu sandik kayitli_secmen oy_kullanan
##   <chr> <chr>      <chr>      <chr>  <dbl>          <dbl>       <dbl>
## 1  Uşak Banaz Cumhuriyet    Mahalle   1001            312         265

Ufak bir not. Burada kullandığım slice komutu da dplyr’a ait. Satır numarasını yazarak istediğim satırları getirmemi sağlıyor. slice(1) demek birinci satırı getir demektir, slice(1:5) yazsaydım 1 ile 5. satırlar arasını getir demekti (Evet : özel bir ifade.)

Eğer seçeceğimiz sütunlar arasında seçmeyeceğimiz bir sütun yoksa aynı ifadeyi şu şekilde de yazabilirdik.

usak_data %>%
select(il:oy_kullanan) %>%
slice(1)
## # A tibble: 1 × 8
##      il bolge  ilce      cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001            312
##   oy_kullanan
##         <dbl>
## 1         265

Yukarıda il sütunundan oy_kullanan sütununa kadar bütün sütunları getir anlamına gelen : operatörü bulunuyor. Sütunları seçerken isimlerini de değiştirebiliyorsunuz. Mesela sandik yerine sandik_no yazalim.

usak_data %>%
select(il,ilce,cevre,cevre_turu,sandik_no=sandik,kayitli_secmen,oy_kullanan) %>%
slice(1)
## # A tibble: 1 × 7
##      il  ilce      cevre cevre_turu sandik_no kayitli_secmen oy_kullanan
##   <chr> <chr>      <chr>      <chr>     <dbl>          <dbl>       <dbl>
## 1  Uşak Banaz Cumhuriyet    Mahalle      1001            312         265

Eğer tek istediğimiz sütun ismi değiştirmekse ve bazı sütunları veri setinden atmak istemiyorsak rename kullanabiliriz.

usak_data %>%
rename(sandik_no=sandik) %>%
slice(1)
## # A tibble: 1 × 30
##      il bolge  ilce      cevre cevre_turu sandik_no kayitli_secmen
##   <chr> <dbl> <chr>      <chr>      <chr>     <dbl>          <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle      1001            312
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp   dyp anadolu_partisi
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>           <dbl>
## 1         265        258       86    95    63     9     0               1
##   hak_par    kp millet_partisi   hap   mep turk_parti   hkp   ldp
##     <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl> <dbl> <dbl>
## 1       0     0              0     0     0          0     3     0
##   saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp bagimsiz
##            <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>    <dbl>
## 1              0     1          0     0             0     0        0

Tebrikler bir dplyr komutu daha tamamlandı. Sırada arrange var.

dplyr::arrange

arrange komutunun tek yaptığı şey sıralamak. Sanırım daha basit anlatılamaz. Sıralamak istediğiniz sütunu/sütunları yazıyorsunuz. Normal davranışı küçükten büyüğe sıralama olsa da eğer sütunu desc() komutunun içerisine alırsanız büyükten küçüğe sıralama yaparsınız. Örneğin AK Parti’nin en çok oy aldığı 5 sandığı görelim.

usak_data %>%
arrange(desc(ak_parti)) %>%
slice(1:5)
## # A tibble: 5 × 30
##      il bolge        ilce    cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl>       <chr>    <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Uşak Merkez   Sorkun        Köy   1490            319
## 2  Uşak     1 Uşak Merkez Karaağaç    Mahalle   1230            372
## 3  Uşak     1 Uşak Merkez Karaağaç    Mahalle   1235            373
## 4  Uşak     1        Eşme Uluyayla        Köy   1118            388
## 5  Uşak     1 Uşak Merkez Karaağaç    Mahalle   1234            373
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp   dyp anadolu_partisi
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>           <dbl>
## 1         305        300      226    11    42     9     0               0
## 2         352        345      224    24    82     4     1               0
## 3         356        344      217    37    80     2     0               0
## 4         368        360      216    48    89     0     0               0
## 5         358        350      213    27    86     2     0               0
##   hak_par    kp millet_partisi   hap   mep turk_parti   hkp   ldp
##     <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl> <dbl> <dbl>
## 1       0     0              1     0     0          0     0     0
## 2       0     0              0     0     0          0     0     0
## 3       0     0              1     0     0          0     0     0
## 4       0     0              0     0     0          0     1     0
## 5       0     0              0     0     0          0     4     0
##   saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp bagimsiz
##            <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>    <dbl>
## 1              8     1          0     0             0     2        0
## 2              6     3          0     0             0     1        0
## 3              5     1          0     0             0     1        0
## 4              3     3          0     0             0     0        0
## 5              4     1          0     1             1    11        0

arrange içerisine birden çok sütun ismi yazabilirsiniz. Önce ilkine göre sıralama yapar, daha sonra ilk sütundaki eşit değerler arasında ikincisine göre, sonra üçüncüsü derken son sütuna kadar aynı şekilde devam eder.

Takır takır bitiriyorsunuz komutları, sırada distinct var.

dplyr::distinct

distinct içerisinde belirtilen sütun veya sütunlar arasından tekrar eden satırları siler. Örneğin distinct(ilce) yazdığımızda eğer bir ilçenin ismi birden fazla satırda geçiyorsa ikinci ve sonraki bütün satırları siler. Örnek kullanım olarak her ilçede AK Parti’ye en çok oy atan sandıkları bulalım.

usak_data %>%
arrange(desc(ak_parti)) %>%
distinct(ilce,.keep_all=TRUE)
## # A tibble: 6 × 30
##      il bolge        ilce    cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl>       <chr>    <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Uşak Merkez   Sorkun        Köy   1490            319
## 2  Uşak     1        Eşme Uluyayla        Köy   1118            388
## 3  Uşak     1     Sivaslı Cinoğlan        Köy   1037            379
## 4  Uşak     1   Karahallı Alfaklar        Köy   1012            288
## 5  Uşak     1      Ulubey  Dilaver    Mahalle   1007            367
## 6  Uşak     1       Banaz Yazıtepe        Köy   1100            317
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp   dyp anadolu_partisi
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>           <dbl>
## 1         305        300      226    11    42     9     0               0
## 2         368        360      216    48    89     0     0               0
## 3         365        363      189   150    12     4     1               0
## 4         256        252      179    34    25     1     0               0
## 5         319        310      159    61    77     2     0               0
## 6         251        239      158    11    56     0     1               2
##   hak_par    kp millet_partisi   hap   mep turk_parti   hkp   ldp
##     <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl> <dbl> <dbl>
## 1       0     0              1     0     0          0     0     0
## 2       0     0              0     0     0          0     1     0
## 3       0     0              0     0     0          0     3     0
## 4       0     0              0     1     1          0     1     0
## 5       0     0              0     0     0          0     2     0
## 6       0     0              0     1     0          0     4     0
##   saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp bagimsiz
##            <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>    <dbl>
## 1              8     1          0     0             0     2        0
## 2              3     3          0     0             0     0        0
## 3              3     1          0     0             0     0        0
## 4              2     1          2     1             1     3        0
## 5              6     3          0     0             0     0        0
## 6              1     2          0     2             1     0        0

Yukarıdaki kodda .keep_all=TRUE parametresi distinct komutunu çalıştırdıktan sonra, R’ın bütün sütunları mı yoksa sadece distinct’e konu olan sütunu mu tutacağını belirtir. Parametreyi FALSE değerine çevirip aradaki farka bakabilirsiniz.

Eğer distinct’e birden fazla sütun yazsaydık sadece distincte konu olan her sütunu aynı olan satırları atacaktı. Örneğin Uşak’ın ilçelerindeki mahalle ve köy isimlerini türleriyle istediğimizi düşünelim.

usak_data %>%
distinct(ilce,cevre,cevre_turu) %>%
slice(1:5)
## # A tibble: 5 × 3
##    ilce       cevre cevre_turu
##   <chr>       <chr>      <chr>
## 1 Banaz  Cumhuriyet    Mahalle
## 2 Banaz       Dilek    Mahalle
## 3 Banaz Hamamboğazı    Mahalle
## 4 Banaz       İslam    Mahalle
## 5 Banaz    Şehitler    Mahalle

Tebrikler bu da bitti! Ancak prenses başka kalede. Sırada mutate ve transmute fonksiyonları bulunuyor.

dplyr::mutate/transmute

Paketin belki de en önemli fonksiyonlarından biri mutate. mutate sayesinde sütunların üzerinde işlemler yapabiliyoruz. Örneğin sandıkların seçime katılım oranlarını bulalım. Katılım oranı oy kullanan seçmen sayısının sandıktaki kayıtlı seçmen sayısına bölümü ile bulunabilir.

usak_data %>%
#yüzdesel değer vermek için oranı 100 ile çarpıp sadece 2 ondalık değeri alıyoruz
mutate(katilim_orani=round(100*(oy_kullanan/kayitli_secmen),2)) %>%
#select ile sadece istediğimiz sütunları da alalım
select(il:sandik,katilim_orani) %>%
slice(1:5)
## # A tibble: 5 × 7
##      il bolge  ilce      cevre cevre_turu sandik katilim_orani
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>         <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001         84.94
## 2  Uşak     1 Banaz Cumhuriyet    Mahalle   1002         83.71
## 3  Uşak     1 Banaz Cumhuriyet    Mahalle   1003         85.21
## 4  Uşak     1 Banaz Cumhuriyet    Mahalle   1004         86.26
## 5  Uşak     1 Banaz Cumhuriyet    Mahalle   1005         87.03

Yukarıda gördüğünüz gibi katilim_orani diye yeni bir sütun yaratıp ilgili sütunları seçtik. round fonksiyonu sayıları yuvarlamaya yarıyor ve fonksiyonun içinde belirtilen diğer değer olan 2 de ondalıktan sonra kaç basamak ilerleyeceğini gösteriyor. Aynı mutate fonksiyonuna birden fazla işlem yazabiliyorsunuz ve var olan sütunların üzerine yazabiliyorsunuz. Dört büyük partinin oy oranlarına bakalım.

usak_data %>%
#yüzdesel değer vermek için oranı 100 ile çarpıp sadece 2 ondalık değeri alıyoruz
mutate(katilim_orani=round(100*(oy_kullanan/kayitli_secmen),2),
        ak_parti=round(100*(ak_parti/gecerli_oy),2),
        chp=round(100*(chp/gecerli_oy),2),
        mhp=round(100*(mhp/gecerli_oy),2),
        hdp=round(100*(hdp/gecerli_oy),2)) %>%
#select ile sadece istediğimiz sütunları da alalım
select(il:sandik,katilim_orani,ak_parti:hdp) %>%
slice(1:5)
## # A tibble: 5 × 11
##      il bolge  ilce      cevre cevre_turu sandik katilim_orani ak_parti
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>         <dbl>    <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001         84.94    33.33
## 2  Uşak     1 Banaz Cumhuriyet    Mahalle   1002         83.71    29.64
## 3  Uşak     1 Banaz Cumhuriyet    Mahalle   1003         85.21    29.73
## 4  Uşak     1 Banaz Cumhuriyet    Mahalle   1004         86.26    21.59
## 5  Uşak     1 Banaz Cumhuriyet    Mahalle   1005         87.03    35.82
##     chp   mhp   hdp
##   <dbl> <dbl> <dbl>
## 1 36.82 24.42  3.49
## 2 33.60 31.23  0.00
## 3 26.25 40.15  2.32
## 4 32.20 44.32  0.00
## 5 31.72 29.48  1.12

transmute fonksiyonu temelde mutate ile aynı. Tek farkı, fonksiyon içerisinde yer alan sütunların dışındaki diğer sütunları veri setinden kaldırıyor. Bir nevi mutate içerisinde select çalıştırıyor.

usak_data %>%
#yüzdesel değer vermek için oranı 100 ile çarpıp sadece 2 ondalık değeri alıyoruz
transmute(sandik,katilim_orani=round(100*(oy_kullanan/kayitli_secmen),2)) %>%
slice(1:5)
## # A tibble: 5 × 2
##   sandik katilim_orani
##    <dbl>         <dbl>
## 1   1001         84.94
## 2   1002         83.71
## 3   1003         85.21
## 4   1004         86.26
## 5   1005         87.03

Aslında bu biraz daha ileri bir konu ama şunu soruyor olabilirsiniz: “Ben bütün partilerin oy oranlarını istiyorsam hepsini elimle tek tek mi yazacağım?” Hayır, gerek yok! Bunun için mutate_each var. Açıklamayacağım ama kodunu yazacağım.

usak_data %>%
mutate_each(funs(round(100*(./kayitli_secmen),2)),ak_parti:bagimsiz) %>%
slice(1:5)
## # A tibble: 5 × 30
##      il bolge  ilce      cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001            312
## 2  Uşak     1 Banaz Cumhuriyet    Mahalle   1002            313
## 3  Uşak     1 Banaz Cumhuriyet    Mahalle   1003            311
## 4  Uşak     1 Banaz Cumhuriyet    Mahalle   1004            313
## 5  Uşak     1 Banaz Cumhuriyet    Mahalle   1005            316
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp   dyp anadolu_partisi
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>           <dbl>
## 1         265        258    27.56 30.45 20.19  2.88     0            0.32
## 2         262        253    23.96 27.16 25.24  0.00     0            0.00
## 3         265        259    24.76 21.86 33.44  1.93     0            0.00
## 4         270        264    18.21 27.16 37.38  0.00     0            0.00
## 5         275        268    30.38 26.90 25.00  0.95     0            0.00
##   hak_par    kp millet_partisi   hap   mep turk_parti   hkp   ldp
##     <dbl> <dbl>          <dbl> <dbl> <dbl>      <dbl> <dbl> <dbl>
## 1       0     0              0     0     0          0  0.96     0
## 2       0     0              0     0     0          0  0.00     0
## 3       0     0              0     0     0          0  0.32     0
## 4       0     0              0     0     0          0  0.00     0
## 5       0     0              0     0     0          0  0.00     0
##   saadet_partisi   dsp yurt_parti    dp vatan_partisi   btp bagimsiz
##            <dbl> <dbl>      <dbl> <dbl>         <dbl> <dbl>    <dbl>
## 1           0.00  0.32          0  0.00          0.00  0.00        0
## 2           2.88  0.32          0  0.00          0.96  0.32        0
## 3           0.00  0.00          0  0.00          0.64  0.32        0
## 4           0.96  0.32          0  0.32          0.00  0.00        0
## 5           0.95  0.00          0  0.00          0.32  0.32        0

mutate ile ilgili derya deniz iş yapılabilir. Son olarak AK Parti, CHP, MHP ve HDP hariç diğer bütün sütunları tek Diğer sütunu altında toplayalım.

usak_data<-
usak_data %>%
mutate(diger=rowSums(.[13:29])) %>%
select(il:hdp,diger)

#Verimizin yeni hali
head(usak_data)
## # A tibble: 6 × 14
##      il bolge  ilce      cevre cevre_turu sandik kayitli_secmen
##   <chr> <dbl> <chr>      <chr>      <chr>  <dbl>          <dbl>
## 1  Uşak     1 Banaz Cumhuriyet    Mahalle   1001            312
## 2  Uşak     1 Banaz Cumhuriyet    Mahalle   1002            313
## 3  Uşak     1 Banaz Cumhuriyet    Mahalle   1003            311
## 4  Uşak     1 Banaz Cumhuriyet    Mahalle   1004            313
## 5  Uşak     1 Banaz Cumhuriyet    Mahalle   1005            316
## 6  Uşak     1 Banaz Cumhuriyet    Mahalle   1006            313
##   oy_kullanan gecerli_oy ak_parti   chp   mhp   hdp diger
##         <dbl>      <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>
## 1         265        258       86    95    63     9    14
## 2         262        253       75    85    79     0    14
## 3         265        259       77    68   104     6    10
## 4         270        264       57    85   117     0     5
## 5         275        268       96    85    79     3     8
## 6         273        270       88    84    87     3    11

rowSums komutu satır toplamlarını veren bir temel R komutudur ancak dplyr altında biraz farklı çalışmaktadır. İleri R konularından biri daha.

Bu kallavi kısmı da bitirdiğimize göre giriş seviyesindeki komutların sonuncu seti olan group_by ve summarise fonksiyonlarına geçebiliriz.

dplyr::group_by/summarise

Eğer veriniz üzerinden daha toplu analizler yapmak istiyorsanız group_by gruplama fonksiyonunu summarise ise yapmak istediğiniz analizleri içeren fonksiyonu ifade ediyor. Örneğin elimizdeki sandık bazındaki veriyi ilçe bazında birleştirmek istiyoruz diyelim. Yapmak istediğimiz analizler ise her ilçedeki sandık sayıları, toplam seçmen sayısı, bir sandıktaki ortalama seçmen sayısı, geçerli oyların seçmen sayısına oranı ve parti oy oranları olsun.

usak_ilce_ozet<-
usak_data %>%
#ilçe bazında grupla
group_by(ilce) %>%
summarise(
    #sandık sayılarını bul
    sandik_sayisi=n(),
    #seçmen sayıları
    toplam_secmen_sayisi=sum(kayitli_secmen),
    #ortalama seçmen sayısı
    ortalama_secmen_sayisi=mean(kayitli_secmen),
    #geçerli oy oranı
    gecerli_oy_orani=sum(gecerli_oy)/sum(kayitli_secmen),
    #parti oy oranları
    ak_parti=round(100*sum(ak_parti)/sum(gecerli_oy),2),
    chp=round(100*sum(chp)/sum(gecerli_oy),2),
    mhp=round(100*sum(mhp)/sum(gecerli_oy),2),
    hdp=round(100*sum(hdp)/sum(gecerli_oy),2),
    diger=round(100*sum(diger)/sum(gecerli_oy),2)
)

usak_ilce_ozet %>%
print(n=Inf)
## # A tibble: 6 × 10
##          ilce sandik_sayisi toplam_secmen_sayisi ortalama_secmen_sayisi
##         <chr>         <int>                <dbl>                  <dbl>
## 1       Banaz           103                27993               271.7767
## 2        Eşme           122                27949               229.0902
## 3   Karahallı            32                 8694               271.6875
## 4     Sivaslı            54                15847               293.4630
## 5      Ulubey            51                11172               219.0588
## 6 Uşak Merkez           507               165245               325.9270
##   gecerli_oy_orani ak_parti   chp   mhp   hdp diger
##              <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>
## 1        0.8673954    34.55 30.70 30.32  0.91  4.41
## 2        0.8758095    33.39 36.53 25.89  1.77  4.18
## 3        0.8515068    42.78 33.78 18.07  1.36  5.34
## 4        0.8715845    37.86 38.77 19.04  1.39  4.29
## 5        0.8892768    35.15 37.26 23.63  0.80  3.95
## 6        0.8917244    39.33 24.76 29.38  2.98  6.51

summarise fonksiyonu bir miktar Excel’de pivot tablo yapmaya benziyor. En büyük farklı daha net ve daha rahat bir şekilde yapılabilmesi. Veriler mümkün olan en granüler haliyle tutulurken bu verilerin doğru bir şekilde birleştirilip analiz edilebilmeleri büyük önem taşıyor.

En son kodda print(n=Inf) gibi bir ifade kullandık. print R’da bir şeyi ekrana yazmak için kullanılan bir fonksiyon olmasına karşılık dplyr bağlamında gösterilecek satır sayısını (n) ifade ediyor. Inf değeri ise sonsuz anlamına geliyor (buradaki anlamıyla bütün satırları göster). Bunu yazmamızın sebebi dplyr tablo gösterimlerinde her zaman bütün satırları yayınlamıyor, burada bütün satırları yayınlamaya zorluyoruz.

Sonuç

Bu döküman geliştirilmeye devam edecektir. Şimdilik dplyr temel fonksiyonları ele alınmış, sırada görselleştirmenin temelleri vardır.

dplyrhakkında daha fazla kaynağa aşağıdaki linklerden ulaşabilirsiniz. Ne yazık ki bütün kaynaklar İngilizce (iyi bilmiyorsanız pratik yapmak için size daha çok fırsat).


  1. Temel bilgisayar kabiliyetleri = Bilgisayarı açıp/kapama, internete girebilme ve program yükleyebilme. Bir miktar İngilizce de faydalı olur.