R Dersleri - Ali Onur Gitmez

Ana Sayfa Ders 1 Ders 2 Ders 3 Ders 4 Ders 5 Ders 6 Ders 7 Ders 8 Ders 9 Ders 10 Ders 11 Ders 12 Ders 13 Ders 14 Ders 15

Veri Yapilari

R kullanirken sadece tekil sayilar veya karakterlerle degil farkli veri yapilari kullanacagiz. Bunlar temel olarak:

  1. Vectors
  2. Factors
  3. Lists
  4. Data Frames
  5. Tibbles
  6. Matrices
  7. Arrays

Bunlarin disinda S3 ve S4 gibi veri tipleri var ancak su anlik onlara giris yapmiyoruz.

Vectors

  • R’in en temel veri tiplerinden birisi
  • Tek boyutlu
  • Sadece ayni tipte olan verileri icerebilir
  • Numeric, character, logical (boolean) gibi farkli tiplerde olabilir

Vektor olusturmak icin farkli yontemler kullanabiliriz.

En temel yontem:

numeric_vector <- c(1,3,6,8)
character_vector <- c("Zeynep" ,"Ece","Onur")
logical_vector <- c(TRUE, FALSE, FALSE, TRUE)
numeric_vector
## [1] 1 3 6 8
character_vector
## [1] "Zeynep" "Ece"    "Onur"
logical_vector
## [1]  TRUE FALSE FALSE  TRUE

Bunlarin hangi tipte vektor oldugunu inceleyelim

typeof(numeric_vector)
[1] "double"
typeof(character_vector)
[1] "character"
typeof(logical_vector)
[1] "logical"
mixed_vector <- c(6, 8, "Ece")
typeof(mixed_vector)
## [1] "character"

Icinde sayilar olmasina ragmen karakter ekledigimiz icin butun vektoru karaktere donusturdu. Ondan dolayi vektor olustururken icindeki elementlerin ayni tipte olduguna dikkat etmemiz gerekiyor. Bu kavrama vector coercion denir.

Diger vektor olusturma yontemleri

: kullanarak sequence vektoru olusturma

sequence_vector <- 1:10
sequence_vector
 [1]  1  2  3  4  5  6  7  8  9 10

seq komutunu kullanarak sequence vektoru olusturma

sequence_vector2 <- seq(1, 10, by = 2)
sequence_vector2
[1] 1 3 5 7 9

rep komutunu kullanarak repetition vektoru olusturma

repeated_vector <- rep(1, times = 5)
repeated_vector
[1] 1 1 1 1 1

Vektor Operasyonlari

Vektorlerin icindeki her bir objeye element denir. Bunlara ayri sekilde ulasabilir, ustunde islem yapabilir ve hatta tum vektorun de dahil oldugu islemler yapabiliriz. Butun vektor ustunde islem yampaya vectorization diyoruz.

Vektorlerin icindeki elementlere erisme:

Bazi programlama dillerinin aksine R vektorlerinde ilk element 0 degil de 1 endeksini alir. Yani ilk elemente erismek istiyorsak

numeric_vector[1]
[1] 1

komutunu kullanmamiz gerekir.

Birden fazla elemente erismek icin ise

numeric_vector[c(1,4)]
[1] 1 8

Eger 2. ve 6. elementler de dahil olmak uzere ulasmak istiyorsak da

sequence_vector[2:6]
[1] 2 3 4 5 6

komutunu kullanmamiz gerekir.

Karilastirma operatorlerini kullanarak da vektorlerden element almamiz mumkun

sequence_vector[sequence_vector > 5]
## [1]  6  7  8  9 10

Diger programlama dillerinin aksine R’da vektorlerde son elementlere, normal elementlere ulasir gibi erismek mumkun degildir. Python’da numeric_vector[-2] yaparak sonda ikinci elemente ulasabilirken, bunu R’da yaparsak ikinci elementi vektorden silmis oluruz.

modified_numeric_vector <- numeric_vector[-2]
numeric_vector
[1] 1 3 6 8
modified_numeric_vector
[1] 1 6 8

Vektor icindeki elementlerin degerlerini degistirmemiz de mumkundur

modified_numeric_vector
[1] 1 6 8
modified_numeric_vector[2] <- 19
modified_numeric_vector
[1]  1 19  8

Benzer sekilde

modified_numeric_vector[2] <- modified_numeric_vector[2] + 6
modified_numeric_vector
[1]  1 25  8

Vectorization

Butun vektoru ayni anda donusturmemize yarayan bir islem tipi

Ornek olarak

double_sequence_vector <- sequence_vector * 2
double_sequence_vector
 [1]  2  4  6  8 10 12 14 16 18 20

Benzer sekilde iki vektoru de isleme sokabiliriz.

numeric_vector2 <- c(6,9,11,4)
new_numeric_vector <- numeric_vector2 + numeric_vector
new_numeric_vector
[1]  7 12 17 12

Vector Recycling

Yukaridaki ornekte vektor islemlerini esit sayida element iceren vektorler ustunden yaptik. Ancak her vektor esit sayida element icermeyecek. Bu durumda R, kisa olan vektorun elementlerini recycle edecek. Yani vektor islemi tamamlanana kadar ne kadar element kullanmasi gerekiyorsa kullanacak.

recycled_vector <- numeric_vector2 + sequence_vector
recycled_vector
 [1]  7 11 14  8 11 15 18 12 15 19

Burada R, ilk olarak iki vektorun de ilk elementini isleme soktu ve bunu dorduncu elemente kadar yapti. Ancak kisa olan vektorumuz burada bittigi icin kisa olan vektorun ilk elementi, uzun olan vektorun besinci elementi ile isleme sokuldu ve vektorler tamamlanana kadar bu devam etti.

R vektorlerini kullanarak aritmetik ve istatistiksel islemler de yapabiliriz.

numberof_votes <- c(156, 223, 97, 134)
total_votes <- sum(numberof_votes)
vote_percentages <- (numberof_votes / total_votes) * 100
vote_percentages
[1] 25.57377 36.55738 15.90164 21.96721

%in% operatoru vektorlerle calisirken isimize yararyacak bir operator. Bir elementin veya bir vektorun elementlerinin baska vektorlerde bulunup bulunmadigini kontrol etmemize yardimci olur.

numeric_vector
[1] 1 3 6 8
sequence_vector
 [1]  1  2  3  4  5  6  7  8  9 10
numeric_vector %in% sequence_vector
[1] TRUE TRUE TRUE TRUE

Bu operatorun daha genis kullanimini bir sonraki konuda gorecegiz. Kullanimi aslinda cok genis bir operator ve cok farkli amaclarla kullanmak mumkun.

Vektorler ustunde slicing islemi de yapabiliriz. Yani vektorun belirli bir kismini secip alabiliriz

sliced_vector <- sequence_vector[3:7]
sliced_vector
[1] 3 4 5 6 7

Benzer sekilde vektorlerde logical islem de yapabiliriz.

sequence_vector > 6
 [1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

Factors

Factors kategorik degiskenleri gostermek adina kullanilan bir vektor tipidir. Siyaset bilimi calismalarinda bolca kullanilir. Ancak kullanimi sadece vektorlerle sinirli degil. Ileride farkli veri tiplerinde de kullanimlarini gorecegiz.

fruits <- factor(c("Portakal", "Elma", "Muz", "Portakal",
                   "Armut", "Muz"))
fruits
[1] Portakal Elma     Muz      Portakal Armut    Muz     
Levels: Armut Elma Muz Portakal

Levels olarak gosterilen kismi bu sekilde de almak mumkun:

levels(fruits)
[1] "Armut"    "Elma"     "Muz"      "Portakal"

Faktorlerin bir avantaji da ordered yani belli bir siraya konabilmesidir.

egitim_seviyesi <- factor(c("Ilkokul","Ortaokul", "Lise",
                            "Universite", "Yuksek Lisans", 
                            "Doktora"),
                    levels = c("Ilkokul", "Ortaokul", "Lise", 
                               "Universite", "Yuksek Lisans", 
                               "Doktora"),
                    ordered = TRUE)
egitim_seviyesi
[1] Ilkokul       Ortaokul      Lise          Universite    Yuksek Lisans
[6] Doktora      
6 Levels: Ilkokul < Ortaokul < Lise < Universite < ... < Doktora

Faktorlerin isimlerini degistirebiliriz. Burada yaptigimiz islem su an icin komplike geliyor olabilir ama ilerleyen vakitte ne kadar kolay oldugunu gorecegiz.

levels(egitim_seviyesi)[levels(egitim_seviyesi) == 
                          "Yuksek Lisans"] <- "Master"
levels(egitim_seviyesi)
[1] "Ilkokul"    "Ortaokul"   "Lise"       "Universite" "Master"    
[6] "Doktora"   

Eger faktor seviyeleri yanlis kodlanmissa bunu degistirebiliriz. Bu ornekte en yuksek egitimi en asagiya aldim. Eger egitimsizligin bir degiskene etkisini olcuyorsak bu sekilde bir kodlama yapmamiz daha mantikli olabilir.

egitim_seviyesi <- factor(egitim_seviyesi, 
                          levels = c("Doktora", "Master", 
                                    "Universite", "Lise",
                                    "Ortaokul", "Ilkokul"))
egitim_seviyesi
[1] Ilkokul    Ortaokul   Lise       Universite Master     Doktora   
Levels: Doktora < Master < Universite < Lise < Ortaokul < Ilkokul

Istersek birden cok faktoru tek bir faktor altinda toplayabiliriz

levels(egitim_seviyesi)[levels(egitim_seviyesi) %in% 
                          c("Universite", "Master", 
                            "Doktora")] <- "Yuksek Okul"
levels(egitim_seviyesi)
[1] "Yuksek Okul" "Lise"        "Ortaokul"    "Ilkokul"    

Faktorlere yeni seviyeler de eklememiz mumkun. Ancak yeni bir seviye ekliyorsak bu faktorlerde en alt seviyeye eklenir. Onu yukariya cikartmak icin reorder yapmamiz gerekir. Ayni zamanda yeni seviye eklememiz onu sadece seviye olarak ekler ve bir data point olarak eklemez. Yani faktor seviyelerine bakarsak gorunur ama bu onun faktoru olustudgumuz zamandaki gibi data point olarak eklenecegini garanti etmez.

levels(egitim_seviyesi) <- c(levels(egitim_seviyesi), "Egitimsiz")
egitim_seviyesi <- factor(c(levels(egitim_seviyesi)[egitim_seviyesi], 
                            "Egitimsiz"), 
                          levels = levels(egitim_seviyesi))
levels(egitim_seviyesi)
[1] "Yuksek Okul" "Lise"        "Ortaokul"    "Ilkokul"     "Egitimsiz"  

Faktor donusumleri

Elimizdeki vektorleri faktore veya faktorleri karaktere donusturmemiz mumkundur.

faktor1 <- as.factor(character_vector)
faktor1
[1] Zeynep Ece    Onur  
Levels: Ece Onur Zeynep

Ayni sekilde faktorleri de karakterlere donusturmemiz mumkundur

character_vector2 <- as.character(egitim_seviyesi)
character_vector2
[1] "Ilkokul"     "Ortaokul"    "Lise"        "Yuksek Okul" "Yuksek Okul"
[6] "Yuksek Okul" "Egitimsiz"  

Eger veri disaridan elimize geldiyse faktorlerin ordered olup olmadigina ve orderin dogru olup olmadigina dikkat etmemiz gerekir. Analize yanlis sekilde sokarsak ortaokul mezuniyeti yuksek lisans mezuniyetinden daha yuksek egitim seviyesine sahipmis gibi gozukebilir

Faktorlerle calismak zor gozukuyor ancak bunu kolaylastiran bir yol var. Bu yol da R paketlerini kullanmaktan geciyor. Faktorler ile daha anlasilir ve kolay sekilde calismak icin forcats paketini kullanacagiz. Bu paket hem faktorlerde daha cok islem yapmaya olanak sagliyor hem de diger islemleri daha anlasiir hale getiriyor.

Ilk olarak paket yoksa yukluyoruz

install.packages("forcats")

Sonra paketi R’da kullanmak uzere guncel sessionimiza aliyoruz

library(forcats)

Eger faktor seviylerinin yerlerini degistirmek istiyorsak

egitim_seviyesi <- fct_relevel(egitim_seviyesi, "Egitimsiz", 
                               "Ilkokul", "Ortaokul", "Lise", 
                               "Yuksek Okul")
levels(egitim_seviyesi)
[1] "Egitimsiz"   "Ilkokul"     "Ortaokul"    "Lise"        "Yuksek Okul"

Eger faktor seviyelerinin ismlerini degistirmek istiyorsak

egitim_seviyesi <- fct_recode(egitim_seviyesi, 
                              "Resmi Egitimi Yok" = "Egitimsiz")
levels(egitim_seviyesi)
[1] "Resmi Egitimi Yok" "Ilkokul"           "Ortaokul"         
[4] "Lise"              "Yuksek Okul"      

Birden cok faktoru tek faktor altinda toplamamiz yine daha kolay

egitim_seviyesi <- fct_collapse(egitim_seviyesi, "Dusuk egitim" 
                                = c("Resmi Egitimi Yok", 
                                    "Ilkokul", "Ortaokul"))
levels(egitim_seviyesi)
[1] "Dusuk egitim" "Lise"         "Yuksek Okul" 

Yeni seviyeler ekleyebiliriz

egitim_seviyesi <- fct_expand(egitim_seviyesi, "Teknik Okul")
levels(egitim_seviyesi)
[1] "Dusuk egitim" "Lise"         "Yuksek Okul"  "Teknik Okul" 

Istemedigimiz seviyeleri cikarabiliriz

egitim_seviyesi <- fct_drop(egitim_seviyesi, only = "Teknik Okul")
levels(egitim_seviyesi)
[1] "Dusuk egitim" "Lise"         "Yuksek Okul" 

Faktorler arasinda az bulunan terimleri Other kategorisine ekleyebiliriz

fruits2 <- factor(c("apple", "banana", "apple", "apple", 
                    "banana", "cherry", "date", "cherry", 
                    "apple", "banana", "elderberry"))
fruits2 <- fct_lump(fruits2, n = 2)
print(fruits2)
 [1] apple  banana apple  apple  banana Other  Other  Other  apple  banana
[11] Other 
Levels: apple banana Other

Faktorleri terse cevirmemiz gerekiyorsa bunu da kolaylikla yapabiliriz

levels(egitim_seviyesi)
## [1] "Dusuk egitim" "Lise"         "Yuksek Okul"
egitim_seviyesi <- fct_rev(egitim_seviyesi)
levels(egitim_seviyesi)
## [1] "Yuksek Okul"  "Lise"         "Dusuk egitim"

Son olaraksa iki faktoru birlestirebiliriz

combined_factor <- fct_c(egitim_seviyesi, fruits2)
print(combined_factor)
 [1] Dusuk egitim Dusuk egitim Lise         Yuksek Okul  Yuksek Okul 
 [6] Yuksek Okul  Dusuk egitim apple        banana       apple       
[11] apple        banana       Other        Other        Other       
[16] apple        banana       Other       
Levels: Yuksek Okul Lise Dusuk egitim apple banana Other

Lists

  • R’in vektorlerden sonraki temel veri tipi
  • Vektorlerin aksine farkli tipte verileri (numeric ve character) bir arada tutabilir, matrisler ve vektorleri icinde barindirabilirhatta baska listeleri de icinde tutabilir (nested lists)
  • Kompleks verileri duzenlemek icin tercih edilebilinecek bir yontemdir.

Olusturma

list1 <- list(3,4, 6:9, TRUE, "R Dersi", c("Muz", "Portakal"))
list1
[[1]]
[1] 3

[[2]]
[1] 4

[[3]]
[1] 6 7 8 9

[[4]]
[1] TRUE

[[5]]
[1] "R Dersi"

[[6]]
[1] "Muz"      "Portakal"

Named List

Liste icindeki her elementin bir isminin oldugu liste tipidir. Bu liste icindeki elemanlari erisme isin kolaylastirir. Ayni zamanda her elemente bir isim atadigimiz icin label gorevi gorur ve hangi elementin ne anlama geldigini anlamamiz kolaylasir.

named_list1 <- list(isim = "Ece", yas = 28, kadin = TRUE)
named_list1
$isim
[1] "Ece"

$yas
[1] 28

$kadin
[1] TRUE

Birden cok ozelligi bulunan verileri kolay bir sekilde depolayabiliriz.

named_list2 <- list(
  marka = "Mercedes",
  model = "E200",
  yil = 2023,
  ozellikler = c("Xenon Far", "Bluetooth", "Kamera")
)
named_list2
$marka
[1] "Mercedes"

$model
[1] "E200"

$yil
[1] 2023

$ozellikler
[1] "Xenon Far" "Bluetooth" "Kamera"   

Liste icindeki elementlere ulasmak icin farkli yontemler kullanilir. Burada onemli bir fark [] kullanimi ile [[]] kullanimi arasindaki farktir. Eger biz tek bracket ile elementleri cagiririsak bu bize elementi degil de o elementi iceren listeyi getirecektir. Yani bizim onu hangi veri tipinde saklamak istedigimizden bagimsiz olarak liste icinden liste formatinda cikaracaktir. Ancak double bracket kullandigimiz durumdaysa istedigimiz elemani kendi veri tipinde cikaracaktir.

Ornek ile anlatmak gerekirse:

class(list1[[1]])
[1] "numeric"
class(list1[1])
[1] "list"

Ilerleyen vakitlerde daha komplike islemler yapacagimiz zaman cikardigimiz veri tipinin onemi gozukecek. Ancak basit bir ornek ile gostermemiz gerekirse, ilki bize sonuc verirken ikincisi error verecek. Bunun sebebi ilkinin numeric olarak cikmasi ve ustunde islam yapilbilmesi ama ikincisinin liste olmasi ve islem yapmanin mumkun olmamasi. Bu durum fonksiyon yazdigimiz zaman kendini daha cok belli edecek.

list1[[1]] + 1
[1] 4
list1[1] + 1

Ancak, listenin icindeki elemanlar nested olabilir. Mesela ilk liste ornegimizde 6 ve 9 arasinda sayilar olusturmustuk. Bu listemizde endeks olarak 3’e aitti.

list1[[3]]
[1] 6 7 8 9

Komutu bize dogrudan o sayilari getirecektir. Eger biz bunlarin icinden bir elemente erismek istiyorsak ikinci bir square bracket kullanmamiz gerekir.

list1[[3]][2]
## [1] 7

Named list kullanmanin bir baska avantaji ise liste icindeki verilere ulasmamizi kolaylastirmasidir. Burada cok kullanacagimiz ve ileride R kullanirken en cok isimize yarayacak operatorlerden birisi de $. Bu operatoru bir veri icinde saklanan diger verilere ulasmak icin kullaniriz. Hem listelerde hem de ileride gorecegimiz dataframelerde isimize yarayacak.

named_list2$ozellikler
[1] "Xenon Far" "Bluetooth" "Kamera"   

Named list kullandgimiz zaman liste icindeki elemanlari guncellemek icin endeksini hatirlamamiza gerek yoktur.

named_list1$isim <- "Zeynep"
named_list1
$isim
[1] "Zeynep"

$yas
[1] 28

$kadin
[1] TRUE

Eger orada element varsa eklmeye yapmak icin

named_list2$ozellikler <- c(named_list2$ozellikler, "Multimedia")
named_list2
$marka
[1] "Mercedes"

$model
[1] "E200"

$yil
[1] 2023

$ozellikler
[1] "Xenon Far"  "Bluetooth"  "Kamera"     "Multimedia"

Cikartmak icin

named_list2$ozellikler <- 
  named_list2$ozellikler[named_list2$ozellikler 
                                                 != "Kamera"]
named_list2
$marka
[1] "Mercedes"

$model
[1] "E200"

$yil
[1] 2023

$ozellikler
[1] "Xenon Far"  "Bluetooth"  "Multimedia"

Named list ile, listelere cok rahat bir sekilde yeni elementler ekleyebiliriz

named_list1$bolum <- "Siyaset Bilimi"
named_list1
$isim
[1] "Zeynep"

$yas
[1] 28

$kadin
[1] TRUE

$bolum
[1] "Siyaset Bilimi"

Benzer sekilde listeden elementleri de cikarabiliriz

named_list1$kadin <- NULL
named_list1
$isim
[1] "Zeynep"

$yas
[1] 28

$bolum
[1] "Siyaset Bilimi"

Listeler ustunde farkli islemler yapabiliriz. Ileride gorecegimiz komutlar burada hizlica islenecek.

Listenin uzunluguna bakmak icin

length(named_list1)
[1] 3

Bir elementin listede bulunup bulunmadigini kontrol etmek icin

"Zeynep" %in% named_list1
[1] TRUE

Listelere element eklememiz de mumkun. Burada after komutunu ekleyerek hangi endekten sonra eklenmesini istedigimizi belirtiyoruz. Bunu belirtmedigimiz durumda otomatik olarak listenin en sonuna atacaktir.

append(list1, "Araba", after = 2)
[[1]]
[1] 3

[[2]]
[1] 4

[[3]]
[1] "Araba"

[[4]]
[1] 6 7 8 9

[[5]]
[1] TRUE

[[6]]
[1] "R Dersi"

[[7]]
[1] "Muz"      "Portakal"

Ayni append komutunu zamanda liste icindeki vektorlere de eklemeler yapabiliriz

named_list2$ozellikler <- append(named_list2$ozellikler, 
                                 "ABS")
named_list2$ozellikler
[1] "Xenon Far"  "Bluetooth"  "Multimedia" "ABS"       

Listelerin avantaji farkli veri tiplerini tutabilmeleridir. Ancak eger vektor ile halledebilecegimiz bir veri girisi varsa list yapmamiza gerek yoktur. Boylece vektorler ustunde yapilacak islemleri de daha kolay bir sekilde yapabiliriz. Vektorler ustunde yapilaak islemleri onumuzdeki hafta daha detaylica isleyecegiz ama bu haftaki ornekte oldugu gibi matematiksel islemler listeler ustunde degil, vektorler ustunde yapilir cunku liste icindeki elementlerin hangi veri tipinde oldugunu umursamaz. Eger liste olarak olusturduysak ve bunu vektore cevirmek istiyorsak unlist komustunu kullanabiliriz.

list2 <- list(3:9, 18, 16)
liste_vektor <- unlist(list2)
liste_vektor
[1]  3  4  5  6  7  8  9 18 16

SON