21  Kontrol yapıları

Bu kısımda ileri seviye R kullanımına başlayacağız. Veri Analizi dersi kapsamında daha çok R ile veri analizi üzerine çalışmalar yapıldı. Bu kısımda ise R ile programlama adımlarını incelemeye başlayacağız.

Kontrol yapıları gerçekleştireceğiniz analiz adımlarında farklı aşamaların çalıştırılması ve veri analizi akışının kontrol edilmesini sağlamaktadır. Bu sayede karmaşık veri setlerinde farklı analiz adımları gerçekleştirebiliriz.

Küçük bir örnekle bunu açıklamaya çalışalım. Elimizde aşağıdaki gibi bir vektör olsun:

yaprak_uzunlugu <- c(2.3, 3.4, 4.5, 1.2, 3.4, 
                    3, 1.8, 6.3, 2.1, 5)

Bu vektörde bulunan her elemana belirli bir fonksiyonu uygulamak istediğimizi düşünelim. Şu ana kadar öğrendiğimiz bilgilerle, bu vektör içerisindeki elemanları manuel olarak seçerek bu işlemleri gerçekleştirebiliyoruz.

Ancak R üzerinde kullanacağımız döngü yapısı (for döngüsü), bize bu vektördeki her elemana erişip, o elemanla işlem yapma şansı sağlamaktadır.

Peki, 5’den büyük ve küçük olan elemanlara farklı işlemler yapmak istersek? O zaman da if-else kontrol yapısı bize yardımcı olacaktır. Bu sayede bir elemanın 5’den büyük veya küçük olma koşulunu inceleyerek, ona göre işlemler gerçekleştirebilriz.

21.1 Döngüler (for)

Veri ile çalışırken çoğunlukla belirli fonksiyonları art arda, farklı verilere uygulamamız gerekir. Dolayısıyla aynı işi döngü halinde yapmalıyız.

Basit bir örnek verelim. Önce bir sayı vektörü oluşturalım:

yaprak_uzunlugu <- c(2.3, 3.4, 4.5, 1.2, 3.4, 
                    3, 1.8, 6.3, 2.1, 5)

Bu vektörün her elemanına 5 ekleyerek çıkan sonucu ikiye bölmek istediğimiz düşünelim. Çok mantıksız bir örnek olabilir ama olayın işleyişini kavramamıza yardımcı olacaktır.

Önce ilk eleman için yapalım. Vektörler ve vektörlerde indisleme konusunu hatırlamak isterseniz Bölüm 8’i tekrar gözden geçirebilirsiniz.

(yaprak_uzunlugu[1]+5)/2
[1] 3.65

Şimdi ise ikinci eleman için bunu yapalım:

(yaprak_uzunlugu[2]+5)/2
[1] 4.2

Dikkat ederseniz sadece kullandığımız vektördeki indis değişiyor. Dolayısıyla for döngüsü kullanırsak bu işi daha kolay bir şekilde halledebiliriz.

Öncelikle for döngüsünün genel yapısına bakalım:

for ( ÇALIŞILACAK ELEMAN KÜMESİ ){
    YAPILACAK İŞ
}

Burada DÖNGÜ ile belirtilen kısma, hangi elemanlardan bir döngü oluşturacağımızı yazıyoruz. for döngüsü bize o elemanları tek tek seçme şansı veriyor. Daha sonra süslü parantezler içerisindeli YAPILACAK İŞ adımı çalıştırılıyor.

Ancak bu yapıyı yukarıdaki gibi kullanmalıyız.

Şimdi döngümüzü yazalım:

for (i in 1:length(yaprak_uzunlugu)){
    sonuc <- (yaprak_uzunlugu[i]+5)/2
    print(sonuc)
}
[1] 3.65
[1] 4.2
[1] 4.75
[1] 3.1
[1] 4.2
[1] 4
[1] 3.4
[1] 5.65
[1] 3.55
[1] 5

Bu işlemi yakından inceleyelim. Önce bir sayı vektörü oluşturuyoruz. Ancak bu sayı vektörünü kullanacağımız vektörün uzunluğuna göre belirliyoruz. Yani elimizde 1’den 10’a kadar bir sayı dizisi oluştuyor.

i in 1:length(yaprak_uzunlugu) cümlesini kullandığımızda R bize elimizdeki eleman kümesini tek tek seçme şansı veriyor.

1:length(yaprak_uzunlugu)
 [1]  1  2  3  4  5  6  7  8  9 10

For döngüsü ise i adından bir değişken oluşturuyor. Önce i değişkenine birinci eleman olan 1 değerini atıyor ve belirtilen işlemi yapıyor.

O işlem bitince, i değerine ikinci elemanı atanıyor ve bu sefer i <- 2 için işlemi gerçekleştiriyor.

Bu işlem oluşturduğumuz sayı vektörü bitene kadar devam ediyor.

Bir önceki örnekte vektördeki eleman sırasını kullandık. İstersek doğrudan vektördeki elemanları da kullanabiliriz. Bunun için ise i yerine eleman isimli bir değişken oluşturalım:

for (eleman in yaprak_uzunlugu){
    sonuc <- (eleman+5)/2
    print(sonuc)
}
[1] 3.65
[1] 4.2
[1] 4.75
[1] 3.1
[1] 4.2
[1] 4
[1] 3.4
[1] 5.65
[1] 3.55
[1] 5

Gördüğünüz iki for döngüsü de aynı işi yapmaktadır. İlk döngüde Bunu şu şekile görselleştirebiliriz (Şekil 21.1).

for ilk Birinci elemanıseçislem İstenen işlemi gerçekleştirilk->islem son Son eleman mı?devam Sonraki elemana geçson->devam FALSEsonlandır Döngüyü sonlandırson->sonlandır TRUEdevam->islem islem->son
Şekil 21.1: for döngüsü hakkındaki diyagram

21.2 Kontrol yapısı (if-else)

Eğer yapacağımız analiz adımında veriye bağlı olarak koşullu bir analiz gerçekleştirilecekse if-else yapısını kullanıyoruz.

Mesela elimizde bir sayımız olsun. Eğer bu sayı 5’ten büyük veya eşit ise ekrana “Bu sayı 5’den büyük veya eşittir” yazsın. Eğer 5’ten küçük ise “Bu sayı 5’den küçüktür” yazsın.

Şekil 21.2 bize bu işlemi şematize edecektir.

g sayi Sayıkontrol 5'den büyük veya 5'e eşitsayi->kontrol ilk Ekrana yazdır:5'den büyük veya 5'e eşitkontrol->ilk TRUEikinci Ekrana yazdır:5'den küçükkontrol->ikinci FALSEsonlandir İşlemi sonlandırilk->sonlandir ikinci->sonlandir
Şekil 21.2: if-else döngüsü hakkındaki diyagram

İlk olarak bir sayı belirleyelim:

sayi <- 12

İlk koşulu çalıştıralım:

sayi >= 5
[1] TRUE

Bu işlemin sonucunda TRUE değeri geri döndürüldü. Burada bir karşılaştırma işlemi yaptık. Yani elimizdeki sayı 5’e eşit veya 5’ten büyük. Ama asla 5’ten küçük değil.

Şimdi if-else yapısına bakalım:

if ( KOŞUL ){
    KOŞUL DOĞRU İSE BURAYI ÇALIŞTIR
} else {
    KOŞUL DOĞRU DEĞİL İSE BURAYI ÇALIŞTIR
}

İlk önce bir koşul belirliyoruz (sayının 5’e eşit veya 5’ten büyük olması). Eğer bu koşul doğru ise ilk yapı çalışıyor, eğer bu koşul doğru değil ise ikinci satır çalışıyor.

Şimdi bu örnek ile gerçekten çalışabilir bir kod yazalım:

sayi <- 12

if (sayi >= 5) {
  print("bu sayi bese esit veya besten buyuktur")
} else{
  print("bu sayi besten kucuktur")
}
[1] "bu sayi bese esit veya besten buyuktur"

21.3 Farklı yapıları birleştirelim

Şimdi tekrar yaprak uzunluğu örneğimize gelelim ve bu iki yapıyı birleştirelim. Bu sefer her elemana farklı işlemler uygulamaya çalışalım.

yaprak_uzunlugu <- c(2.3, 3.4, 4.5, 1.2, 3.4, 
                    3, 1.8, 6.3, 2.1, 5)

Elimizde artık iki tane koşul olsun:

  • Eğer eleman 5’den büyük veya eşitse elemana 5 ekle ve ikiye böl.
  • Eğer eleman 5’den küçükse elemana 10 ekle ve 3’e böl.

Yine örneğimiz biraz rastgele oldu. Böyle bir senaryo için if-else yapısı kullanmalıyız. Önce cevabı görelim, daha sonra adım adım inceleyelim:

for (eleman in yaprak_uzunlugu){
    if (eleman >= 5){
        sonuc <- (eleman+5)/2
        cat("yaprak uzunlugu 5'den buyuk veya esit, ilk formul uygulandı:", sonuc, "\n")
    } else {
        sonuc <- (eleman+10)/3
        cat("yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı:", sonuc, "\n")
    }
}
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.1 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.466667 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.833333 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 3.733333 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.466667 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.333333 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 3.933333 
yaprak uzunlugu 5'den buyuk veya esit, ilk formul uygulandı: 5.65 
yaprak uzunlugu 5'den kucuk, ikinci formul uygulandı: 4.033333 
yaprak uzunlugu 5'den buyuk veya esit, ilk formul uygulandı: 5 

Şimdi bu yapıyı daha iyi anlamak için görselleşirelim (Şekil 21.3):

g eleman Birinci elemanı seçkontrol 5'den büyük veya 5'e eşit mi?eleman->kontrol ilk Birinci formülü uygulaSonucu ekrana yazdırkontrol->ilk TRUEikinci İkinci formülü uygulaSonucu ekrana yazdırkontrol->ikinci FALSEson Son eleman mı?devam Sonraki elemanı seçson->devam FALSEDöngüyü sonlandır. Döngüyü sonlandır.son->Döngüyü sonlandır. TRUEilk->son ikinci->son devam->kontrol Başla BaşlaBaşla->eleman
Şekil 21.3: İki kontrol yapısını da birleştirmek

21.4 Ödev

Burada öğrendiklerimizi pekiştirmek için ?sec-odev-dna-islemler’de bulunan ödeve bakalım ve haftaya kadar cevaplayalım.