R Dilinde Loop (Döngü) İşlemleri
R programalam dili ile ilgili yazılar, basit örnekler dahilinde loop konusuna (repetitive execution) değinerek devam ediyorum.
R dilinde döngüler (loop construction) for
(for (name in expr_1) expr_2
), repeat
(repeat expr) ve while
(while (condition) expr) ile oluşturulur. loop
, cycling
ya da iterating
hangi tanımı kullandığınız önemli değil. Temelde, çok adımlı bir süreci, eylem dizilerini ve toplu işlemleri organize etmek ve tekrarlanmasını sağlamak amacıyla kullanılan en temel işlemlerden biri olduğunuz bilmeniz yeterli. Herhangi bir programlama diline aşinalığınız varsa zaten daha öncesinde kullanmış ya da en azından örneklerde rastlamışsınızdır. R dilinde de döngülerin işleme biçimleri dilin bağlamı haricinde aynı. İlk olarak for döngüsü ile başlayalım. Ancak öncesinde oldukça basit bir işlem oluşturalım ve bu işlemi döngülerle yeniden kurgulayalım.
print(paste("Number is", 1)) # Number is 1
print(paste("Number is", 2)) # Number is 2
print(paste("Number is", 3)) # Number is 3
print(paste("Number is", 4)) # Number is 4
print(paste("Number is", 5)) # Number is 5
For Loop
For döngüsü belirli bir kod bloğunu (name) belirtilen sayıda (expr_1
, vector expression1. Örneğin, 1:20
) ve peş peşe çalıştırmak (expr_2
, grouped expression) (belirtilen i
. değerden belirten j
. değerine kadar) için kullanılır.
for (name in _expr_1_) _expr_2_
Yukarıdaki kullanımı hatırlayalım. Aşağıdaki uygulamamızın ilk satırında yer alan c(1:5)
vektör içeriğini (1,2,3,4,5, first_value:1
, end_value:5
) number’a atıyoruz. Ekrana yazdırdığımız ikinci satırda paste içeriğinde “Number is” string ifadesini de dahil ederek sayımızı sırasıyla ekrana basıyoruz ve çıktımız yukarıda el yordamı ile satır satır yazdığımız Number is x dökümü ile aynı oluyor.
for (number in c(1:5)){
print(paste("Number is", number))
}
Elbette yukarıdaki for’un işlevini daha net anlamak adına print(c(1:5))
kodunu ayrıca uygulayabilirsiniz. Alacağınız karşılık [1] 1 2 3 4 5
olacaktır. Ayrıca bir de şu örneği deneyebilirsiniz:
for(number in c(1:5)){
print(c(1:number))
}
Yukarıdaki örnek, expr_1
içeriğini sırayla number’a atayacak, print
ise 1:number
değer aralıklarını gökecektir. Ek olarak aşağıdaki örneği uygulayarak print içeriğindeki farklılığı daha net görebilirsiniz.
for(number in c(1:5)){
print(number)
}
Son bir örnekle for döngüsünü noktalayabiliriz.
for (number in 1:5){
print(paste(number, "^2:", number^2))
}
While Loop
While döngüsü belirlenen koşul (condition) sağlandığı sürece işlemi (expr) uygulayan temel döngü yapılarından bir tanesidir. BAsitliği ile tercih edilen while temel yapısı şu şekildedir.
while (condition) _expr_
Yine yazının başındaki örnek üzerinden devam edeceğim.
number <- 1
while (number <= 5){
print(paste("Number is", number))
number <- number + 1
}
Yukarıdaki örnekte number değerine 1 sayısını atıyoruz. while tanımlanan condition sağlandığı sürece number <= 5
ekrana print içeriğini dökecektir. Print sonrasındaki number içeriğimiz bir önceki içeriğe +1
ekleyerek condition boyunca döngüyü sürdürecektir. Örnekteki number <- number + 1
satırını print üzerine ekleyerek kodu tekrar çalıştırdığınızda sonucun değiştiğini görebilirsiniz. Son olarak, repeat
örneklerinden bahsedeceğim ve sonrasında iç içe döngüler, break
ve next
kullanımlarıyla yazısı sonlandıracağım.
Repeat Loop
Repeat, belirtilen expr if...else... ile belirtilen condition durumuna bağlı olarak tekrar edilecektir. En temel kullanım şekli şöyle:
repeat _expr_
Öncelikle aşağıda herhangi bir condition barındırmayan bir repeat
işlemi uygulayalım.
number <- 1
repeat {
print(paste("Number is", number))
number = number+1
}
Göreceğiniz üzere print aksi belirtilmediği ve işlem sonlandırılmadığı sürece değer dökecektir. Şimdi, bir condition ekleyelim ve print içeriğinin 5'ten büyük number > 5
olduğu durumda basılmamasını, break
ile repeat
işleminin durdurulmasını belirtelim2.
number <- 1 repeat { print(paste("Number is", number)) number = number+1 if (number > 5){
break
}
}
Hazır if...else...
condition içeriğinde break işlemine değişmişken bir sonraki başlığıma geçebiliriz.
R Dilinde Next ve Break Kullanımı
Özellikle döngülerde sıklıkla denk gelebileceğiniz break
ve next
kullanımını yine örnekler üzerinden açıklayayım. En temel kullanım biçimini aşağıda iletiyorum.
repeat{
_expr_
if(condition){
break
}
}
Önce break
işlevinden bahsedeyim. İçeriğinde (scope) yer aldığı condition sağlandığı durumda bağlı olduğu döngü ve/veya fonksiyonunu durduracaktır. Bir sonraki scope içeriğindeki sonraki işleme geçilecektir.
number <- 1
while(number < 10) { print(number); number <- number + 1; if (number == 3) break; }
next
ise içeriğinde yer aldığı condition sağlandığında bir sonraki adıma geçecektir.
number <- 1
while(number < 5) { number <- number + 1; if (number == 3) next; print(number); }
En temel kullanım biçimlerini bu şekilde özetleyebileceğimiz break
ve next
'in ardından son olarak iç içe döngülere değinelim.
R Dilinde İç İçe Döngüler
number <- matrix(1:6, 2, 3)
for(i in seq_len(nrow(number))) {
for(j in seq_len(ncol(number))) {
print(c(number[i, j])) # print(number[i, j])
}
}
Örnekte 2 adet for döngüsü görmektesiniz. seq
fonksiyonuna ayrıca başka bir yazıda değineceğim. Basitçe açıklamak gerekirse seq
fonksiyonu3 düzenli diziler oluşturmamızı seq.int
, seq_along
, seq_len
sağlar. İlk for i
içeriğine oluşturduğumuz matrix'in sütun değerini atayacaktır. İkinci for
satır değerini j
içeriğine atayacaktır ve ekrana döngüyle eşleşen satır-sütun değerleri i-j
basılacaktır.
[1] 1
[1] 3
[1] 5
[1] 2
[1] 4
[1] 6
Bir diğer örnekte de farklı bir iç içe döngü (nested) ile aşağıdaki çıktığı nasıl oluşturabileceğimize bakalım.
1
2 2
3 3 3
...
Yukarıdaki çıktı için öncelikle bir vector oluşturalım.
vector <- c()
for(i in 1:10) {
for(j in 1:i) {
vector <- c(vector, i)
}
}
Bu döndünün çıktısı şu şekilde olacaktır.
[1] 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8
[30] 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10
Görüldüğü gibi her sayı kendi tekrarını oluşturmakta. Artık bu çıktıyı tekrar bir döngüye sokabiliriz.
n <- 1
for(n in n:10){
x = (n * (n - 1)) / 2 + 1
y = (n * (n + 1)) / 2
print(vector[x:y])
}
Basit örneklerle açıklamaya çalıştığım döngülerle ilgili daha kapsamlı kullanımları diğer R yazılarım içerisinde görebilirsiniz.
Unutmadan ekleyeyim. Genelde R programlama dili ile yoğun bir şekilde çalışan geliştiriciler for ve while işlemleri veri miktarına bağlı olarak değerlendirilmesi gerektiğini, veri miktarı arttıkça çözümün apply ailesinin daha iyi performans göstereceğini belirtmekteler4 5.