Tarifler: Veri Yapıları
Bütün programlama dillerinde olduğu gibi R’da da temel yapı taşları verileri depoladığımız veri yapılarıdır. R’da yapzdığımız her kodun içerisinde bu yapıları kullanmaktayız. Vektör, dizi, matris, liste ve dataframe yapılarının nasıl üretileceği, değiştirileceği, alt gruplara ayrılacağı, dönüştürüleceği gibi konularda yeterli beceriye sahip olursak R’ı çok daha etkin kullanabiliriz.
- Bir vektörün sonuna nasıl yeni bir eleman eklerim?
- Bir vektörün herhangi bir konumuna yeni bir elemanı nasıl eklerim?
- Nasıl faktör (yahut kategorik değişken) oluştururum?
- Birbirleriyle ilişkili vektörleri nasıl data frame’e dönüştürebilirim?
- Nasıl liste oluştururum?
- Liste elemanlarını nasıl seçerim?
- Bir listeden nasıl eleman silerim?
- Bir listeyi vektöre nasıl çevirebilirim?
- Listemde bulunan bazı elemanları belli bir kritere göre silmek istiyorum, nasıl yapabilirim?
- Nasıl yeni bir matris üretebilirim?
- Matrisin satır ve sütunlarına nasıl başlık verebilirim?
- Matrisin sadece bir satır veya sütununu nasıl seçebilirim?
- Vektör olarak kaydedilmiş değişkenleri data frame sütunları olarak birleştirmek istiyorum, nasıl yaparım?
- Vektör olarak kaydedilmiş gözlemleri data frame satırları olarak birleştirmek istiyorum, nasıl yaparım?
- Mevcut bir data frame’e nasıl yeni bir satır eklerim?
- Boş bir data frame oluşturmak istiyorum, nasıl yapabilirim?
- Data frame’de bulunan değişkenlerin konumuna göre seçme işlemini nasıl yaparım?
- Data frame sütunlarını sütun (değişken) isimleriyle nasıl seçebilirim?
- Sütun seçim işlemini daha pratik yapamaz mıyız?
- Data frame’de bulunan değişken isimlerini nasıl değiştirebilirim?
- Data frame’imde
NA
değerleri var ve fonksiyonlar hatalı sonuç veriyor, ne yapabilirim? - İki veya daha fazla data frame’i birleştirmek istiyorum, nasıl yaparım?
with
fonksiyonunu data frame ile nasıl kullanabilirim?
Bir vektörün sonuna nasıl yeni bir eleman eklerim?
Mevcut bir vektöre yeni bir eleman eklemek için yine c()
fonksiyonundan yararlanırız:
a <- c(0,1,2,3,4)
a <- c(a,5)
a
## [1] 0 1 2 3 4 5
Aynı biçimde iki vektörü birleştirebiliriz:
a <- c(0,1,2,3,4)
b <- c(5,6,7,8,9)
a <- c(a,b)
a
## [1] 0 1 2 3 4 5 6 7 8 9
İndeks numarası belirterek te yeni eleman ekleyebiliriz:
a <- c(0,1,2,3,4)
a[6] <- 5
a
## [1] 0 1 2 3 4 5
İndeks numarasıyla ekleme yaparken eleman sayısından büyük bir değer atanması halinde R hata vermeyecektir. Ancak ortaya çıkan vektör pek de istediğiniz gibi olmayabilir. Bu yüzden indeks numarasıyla atama yaparken vektörün büyüklüğünü sorgulamakta fayda var:
a <- c(0,1,2,3,4)
a[10] <- 5
a
## [1] 0 1 2 3 4 NA NA NA NA 5
b <- c(5,6,7,8,9)
b[length(b)+1] <- 10
b
## [1] 5 6 7 8 9 10
Ayrıca append()
fonksiyonuyla da mevcut bir vektöre eleman ekleyebiliriz:
a <- c(0,1,2,3,4)
append(a,c(5,6,7,8,9))
## [1] 0 1 2 3 4 5 6 7 8 9
Bir vektörün herhangi bir konumuna yeni bir elemanı nasıl eklerim?
append
fonksiyonu after
parametresiyle birlikte kullanılarak vektörün herhangi bir konumuna yeni eleman eklenilebilir.
a <- c(0,1,2,3,4,10)
append(a,c(5,6,7,8,9), after = 5)
## [1] 0 1 2 3 4 5 6 7 8 9 10
after
parametresine sıfır değeri verirsek yeni elemanlar vektörün baş tarafına yerleştirilir.
a <- c(0,1,2,3,4,5)
append(a, -1, after = 0)
## [1] -1 0 1 2 3 4 5
Nasıl faktör (yahut kategorik değişken) oluştururum?
factor
fonksiyonuyla veri tipi faktör olan bir değişken üretebiliriz. levels
parametresiyle değişkenin parametrelerini belirleyebiliriz (komutun tamamının paranteze alınması print
fonksiyonunu iş başına çağırır):
a <- c(1,1,3,3,5,5)
(a <- factor(a))
## [1] 1 1 3 3 5 5
## Levels: 1 3 5
(b <- factor(a, levels = c(1,3,5,7,9)))
## [1] 1 1 3 3 5 5
## Levels: 1 3 5 7 9
(c <- factor(c("Pzt","Pzt","Çar","Cu","Cu"),levels= c("Pzt","Sa","Çar","Per","Cu","Cts","Paz")))
## [1] Pzt Pzt Çar Cu Cu
## Levels: Pzt Sa Çar Per Cu Cts Paz
Birbirleriyle ilişkili vektörleri nasıl data frame’e dönüştürebilirim?
Farzedelim üç farklı ilin hava kirliliği değerlerini ölçtük, yine farzedelim bu ölçümler 5 ila 10 arasında rakamlar verdi ve vektör şeklinde kaydettiğimiz bu değerleri bir sütunda birleştirmek istiyoruz. R ile bunu farklı biçimlerde yapmak mümkün. Fakat burada stack
fonksiyonunun kullanımını göreceğiz. Aşağıda öncelikle sample
fonksiyonuyla üç il için rastgele değerler üreteceğim. Sonrasında üç vektörü liste veri tipine dönüştürerek data frame’de bir araya getireceğim:
a <- sample(x = 5:10, size = 12, replace = TRUE)
b <- sample(x = 5:10, size = 12, replace = TRUE)
c <- sample(x = 5:10, size = 12, replace = TRUE)
d <- stack(list(ankara = a, izmir = b, urfa = c))
head(d, 5)
## values ind
## 1 5 ankara
## 2 7 ankara
## 3 9 ankara
## 4 9 ankara
## 5 8 ankara
stack
fonksiyonu liste veri tipi girdi istediğinden öncelikle vektörleri liste haline dönüştürdüm. Sonuç olarak değerleri barındıran values
sütunu ve kategorileri barındıran ind
sütunundan oluşan bir data frame elde ettim.
Nasıl liste oluştururum?
Listeler, farklı veri tiplerini barındıran yapılardır. Liste, list
fonksiyonuyla üretilir:
persn <- list(isim = c("Ali", "Ayşe", "Atıf"), sicil = c(124,132,156), dot = c("1990-03-12","1993-06-24","1991-11-10"), bh = toupper(c("Ali", "Ayşe", "Atıf")) )
str(persn)
## List of 4
## $ isim : chr [1:3] "Ali" "Ayşe" "Atıf"
## $ sicil: num [1:3] 124 132 156
## $ dot : chr [1:3] "1990-03-12" "1993-06-24" "1991-11-10"
## $ bh : chr [1:3] "ALI" "AYŞE" "ATIF"
Görüldüğü üzere liste elemanı olarak fonksiyon da atanabilir. Ayrıca liste elemanlarının eşit büyüklükte olmaları da gerekmez. Bu biçimiyle listeler herşeyi içine atabileceğiniz torba gibidirler.
Listeler boş olarak üretilip sonradan doldurulabilir. Özellikle program yazarken bu yöntem kullanışlı olmaktadır:
persn <- list()
persn[[1]] <- c("Ali", "Ayşe", "Atıf")
persn[[2]] <- c(124,132,156)
persn[[3]] <- c("1990-03-12","1993-06-24","1991-11-10")
persn[[4]] <- toupper(persn[[1]])
names(persn) <- c("isim","sicil","dot","bh")
str(persn)
## List of 4
## $ isim : chr [1:3] "Ali" "Ayşe" "Atıf"
## $ sicil: num [1:3] 124 132 156
## $ dot : chr [1:3] "1990-03-12" "1993-06-24" "1991-11-10"
## $ bh : chr [1:3] "ALI" "AYŞE" "ATIF"
Sondan bir önceki komutta names
fonksiyonuyla liste elemanlarına isim verdik. Bunun yerine yine boş bir liste üretip, listeye atama yaparken isim verebiliriz. Bunun için liste ve data frame’lerde kullandığımız $
anahtarını kullanmalıyız:
persn <- list()
persn$isim <- c("Ali", "Ayşe", "Atıf")
persn$sicil <- c(124,132,156)
persn$dot <- c("1990-03-12","1993-06-24","1991-11-10")
persn$bh <- toupper(persn[[1]])
str(persn)
## List of 4
## $ isim : chr [1:3] "Ali" "Ayşe" "Atıf"
## $ sicil: num [1:3] 124 132 156
## $ dot : chr [1:3] "1990-03-12" "1993-06-24" "1991-11-10"
## $ bh : chr [1:3] "ALI" "AYŞE" "ATIF"
Liste elemanlarını nasıl seçerim?
Liste veri türünde liste elemanlarını seçerken tek köşeli parantez kullanırsak liste, çift köşeli parantez kullanırsak vektör olarak çıktı alırız. Bu küçük fark bazen uğraştırıcı hatalara düşmemize sebep olduğundan akıldan çıkarılmamalıdır:
persn[1]
## $isim
## [1] "Ali" "Ayşe" "Atıf"
persn[[1]]
## [1] "Ali" "Ayşe" "Atıf"
Vektörlerde olduğu gibi birden fazla elemanı aynı anda seçebiliriz:
persn[c(1,3)]
## $isim
## [1] "Ali" "Ayşe" "Atıf"
##
## $dot
## [1] "1990-03-12" "1993-06-24" "1991-11-10"
Çift parantez kullandığımızda, yani vektör olarak çıktı aldığımızda bu işlem farklı bir sonuç verecektir:
persn[[c(1,3)]]
## [1] "Atıf"
persn[[c(1,3)]]
biçiminde yazdığımızda persn listesinin birinci elemanının, üçüncü ögesini seçmiş olduk. Bu şekilde listede eleman seçimi yapabiliriz.
Liste elemanlarını adlarıyla da seçebiliriz:
persn["isim"]
## $isim
## [1] "Ali" "Ayşe" "Atıf"
persn[["isim"]]
## [1] "Ali" "Ayşe" "Atıf"
persn$isim
## [1] "Ali" "Ayşe" "Atıf"
Görüldüğü gibi son iki komut şekli aynı sonucu vermektedir. $
anahtarı aynı data frame’lerde olduğu gibi liste elemanını vektör biçiminde çıktı olarak getirir.
Toparlayacak olursak; liste elemanlarını seçerken, tek köşeli parantez (x[n]
) liste, çift köşeli parantez (x[[n]]
) ve dolar işareti (x$n
) vektör olarak çıktı verir.
Bir listeden nasıl eleman silerim?
Listeden bir eleman silmek için silmek istediğimiz elemana NULL
değeri atarız:
persn
## $isim
## [1] "Ali" "Ayşe" "Atıf"
##
## $sicil
## [1] 124 132 156
##
## $dot
## [1] "1990-03-12" "1993-06-24" "1991-11-10"
##
## $bh
## [1] "ALI" "AYŞE" "ATIF"
persn[["bh"]] <- NULL
persn
## $isim
## [1] "Ali" "Ayşe" "Atıf"
##
## $sicil
## [1] 124 132 156
##
## $dot
## [1] "1990-03-12" "1993-06-24" "1991-11-10"
Yukarıda çift köşeli parantez ve eleman ismini kullandık. Bunun yerine yine çift köşeli parantez ve silmek istediğimiz elemanın indeks değerini persn[[4]]
veya persn$bh
şeklindeki tanımlamaları da kullanabiliriz.
Bir listeyi vektöre nasıl çevirebilirim?
Evet çevirebiliriz. Bunun için unlist
fonksiyonundan yararlanırız. Bazı R fonksiyonları sadece vektörler üzerinde işlem yapar. Yine bazı R fonksiyonları liste olarak çıktı verir. Liste şeklindeki bir çıktıyı vektörlerle çalışan bir fonksiyona atadığımızda hata mesajı alırız. Bu sebeple listeyi öncelikle vektöre dönüştürmemiz gerekir:
degerler <- list(c(1,2,4,2,6,9,1,2,1,9,7,8,3,2))
mean(degerler)
## Warning in mean.default(degerler): argument is not numeric or logical: returning
## NA
## [1] NA
mean(unlist(degerler))
## [1] 4.071429
Listemde bulunan bazı elemanları belli bir kritere göre silmek istiyorum, nasıl yapabilirim?
Listede bulunan elemanları mantıksal karşılaştırmalarla seçebiliyorsak, seçtiğimiz elemanları silebiliriz de. Mesela listede bulunan negatif değerleri şöyle silebiliriz:
(lst <- -5:10)
## [1] -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10
lst <- lst[-(which(lst < 0))]
lst
## [1] 0 1 2 3 4 5 6 7 8 9 10
Nasıl yeni bir matris üretebilirim?
matrix
fonksiyonu ile matris üretebiliriz. matrix
fonksiyonu temel olarak matrise yerleşecek veriyi ve matrisin satır sütun sayısını parametre olarak alır. Mesela iki satır, üç sütundan müteşekkil (2x3) bir matris üretelim:
vec <- round(rnorm(12,5,2), digits = 1)
matrix(vec,3,4)
## [,1] [,2] [,3] [,4]
## [1,] 6.9 8.0 7.2 4.6
## [2,] 6.0 5.9 5.4 3.8
## [3,] 9.7 2.3 6.8 2.7
vec
vektörü matrise dönüştürülürken veriler sırasıyla sütunlar esas alınarak yazılır. Yani önce birinci, ardından ikinci ve sonraki sütunlar oluşturulur. Verisi satır temelli yazmak için byrow
parametresine TRUE
değerini atamalıyız.
matrix(vec,3,4,byrow = TRUE)
## [,1] [,2] [,3] [,4]
## [1,] 6.9 6.0 9.7 8.0
## [2,] 5.9 2.3 7.2 5.4
## [3,] 6.8 4.6 3.8 2.7
Herhangi bir veri içermeyen boş bir matris te üretebiliriz:
matrix(NA,3,4)
## [,1] [,2] [,3] [,4]
## [1,] NA NA NA NA
## [2,] NA NA NA NA
## [3,] NA NA NA NA
Son olarak herhangi bir vektöre boyut ekleyerek te matris üretebiliriz:
dim(vec) <- c(4,3)
vec
## [,1] [,2] [,3]
## [1,] 6.9 5.9 6.8
## [2,] 6.0 2.3 4.6
## [3,] 9.7 7.2 3.8
## [4,] 8.0 5.4 2.7
Matrisin satır ve sütunlarına nasıl başlık verebilirim?
Matris satırlarını rownames
, sütunlarını colnames
fonksiyonları ile başlıklandırabiliriz:
vec <- round(rnorm(12,5,2), digits = 1)
dim(vec) <- c(3,4)
rownames(vec) <- c("X","Y","Z")
colnames(vec) <- c("A","B","C","D")
vec
## A B C D
## X 1.6 3.4 4.4 4.2
## Y 4.5 6.0 5.8 1.9
## Z 2.5 5.8 3.2 4.9
Matrisleri başlıklandırmanın avantajlı tarafı, başlıkları kullanarak matris elemanlarını seçebiliriz:
vec["Y","C"]
## [1] 5.8
Matrisin sadece bir satır veya sütununu nasıl seçebilirim?
Matriste yer alan bir veriyi seçerken matrisin adından sonra köşeli parantez içerisinde önce satır sonra sütun başlığını veya indisini belirtmemiz gerekir:
vec[2,3] # veya vec["Y","C"]
## [1] 5.8
Bir satır seçerken yapmamız gereken satır bilgisini yazıp sütun bilgisini boş bırakmak olacaktır. Aynı biçimde tek bir sütun seçerken yapmamız gereken sütun bilgisini yazıp, satır bilgisini boş bırakmaktır:
vec[2,] # ikinci satırı seçer
## A B C D
## 4.5 6.0 5.8 1.9
vec[,3] # üçüncü sütunu seçer
## X Y Z
## 4.4 5.8 3.2
Bu seçim işlemi bir vektör üretecektir. Tek satırlı veya sütunlu matris elde etmek için drop=FALSE
parametresini eklemeliyiz:
vec[2,,drop=FALSE] # ikinci satırı seçer
## A B C D
## Y 4.5 6 5.8 1.9
vec[,3,drop=FALSE] # üçüncü sütunu seçer
## C
## X 4.4
## Y 5.8
## Z 3.2
Vektör olarak kaydedilmiş değişkenleri data frame sütunları olarak birleştirmek istiyorum, nasıl yaparım?
Vektörlerden data frame oluşturmak için data.frame
fonksiyonundan yararlanırız. Ufak bir ayrıntı, vektörlerin eşit uzunlukta olmaları gerekmektedir:
var1 <- round(rnorm(10,5,2), digits = 1)
var2 <- round(rnorm(10,10,2), digits = 1)
var3 <- sample(c("A","B"),10,replace = TRUE)
var4 <- round(rnorm(10,15,2), digits = 1)
df1 <- data.frame(var1,var2,var3,var4)
df1
## var1 var2 var3 var4
## 1 1.5 10.4 A 14.8
## 2 4.9 11.9 A 16.8
## 3 4.5 8.6 A 19.0
## 4 3.4 8.4 B 18.0
## 5 3.5 8.8 A 15.8
## 6 3.4 9.0 B 19.6
## 7 8.4 11.9 A 16.1
## 8 2.7 8.2 B 11.5
## 9 6.3 13.6 B 17.1
## 10 4.7 9.6 B 19.1
Görüldüğü üzere R sütun başlıklarını değişken ismi olarak aldı. İstersek değişken adlarını kendimiz belirleyebiliriz:
df1 <- data.frame(height=var1,length=var2,type=var3,width=var4)
df1
## height length type width
## 1 1.5 10.4 A 14.8
## 2 4.9 11.9 A 16.8
## 3 4.5 8.6 A 19.0
## 4 3.4 8.4 B 18.0
## 5 3.5 8.8 A 15.8
## 6 3.4 9.0 B 19.6
## 7 8.4 11.9 A 16.1
## 8 2.7 8.2 B 11.5
## 9 6.3 13.6 B 17.1
## 10 4.7 9.6 B 19.1
Verimiz farklı farklı vektörlerde değil de bir listede depolanmışsa as.data.frame
fonksiyonundan faydalanabiliriz:
lst <- list(height=var1,length=var2,type=var3,width=var4)
lst
## $height
## [1] 1.5 4.9 4.5 3.4 3.5 3.4 8.4 2.7 6.3 4.7
##
## $length
## [1] 10.4 11.9 8.6 8.4 8.8 9.0 11.9 8.2 13.6 9.6
##
## $type
## [1] "A" "A" "A" "B" "A" "B" "A" "B" "B" "B"
##
## $width
## [1] 14.8 16.8 19.0 18.0 15.8 19.6 16.1 11.5 17.1 19.1
df1 <- as.data.frame(lst)
df1
## height length type width
## 1 1.5 10.4 A 14.8
## 2 4.9 11.9 A 16.8
## 3 4.5 8.6 A 19.0
## 4 3.4 8.4 B 18.0
## 5 3.5 8.8 A 15.8
## 6 3.4 9.0 B 19.6
## 7 8.4 11.9 A 16.1
## 8 2.7 8.2 B 11.5
## 9 6.3 13.6 B 17.1
## 10 4.7 9.6 B 19.1
Listeyi data frame’e çevirirken liste elemanlarının tanımlayıcı birer adının olması önem arzediyor, yoksa anormal sonuçlar alabilirsiniz.
Görüldüğü gibi her iki işlem de eldeki veriyi sütun olarak kullandı.
Vektör olarak kaydedilmiş gözlemleri data frame satırları olarak birleştirmek istiyorum, nasıl yaparım?
Yukarıda her vektörün ayrı bir değişken olması halinde nasıl data frame olarak birleştirilebileceğini gördük. Ancak bazen veriseti değişkenler değilde gözlemler olarak elimize gelir. Yani her vektör bir gözlem verisi içerir. Yani sütunları değil satırları oluşturmaktadırlar. Bu durumda rbind
fonksiyonunu kullanırız. Ancak rbind
her seferde bir vektörü data frame ile birleştirmektedir. Bu sebeple öncelikle vektörleri bir liste yapısında bir araya getirecek sonra rbind
ile birleştireceğim. Aşağıda, önce bir döngü yardımıyla rastgele sayılardan oluşan 10 vektör oluşturacağım:
lst <- list()
for (i in 1:10) lst[[i]] <- c(rnorm(4,10,1))
lst
## [[1]]
## [1] 9.604798 10.781800 9.801167 10.741509
##
## [[2]]
## [1] 10.747974 11.614187 9.838524 12.590411
##
## [[3]]
## [1] 8.600719 10.340999 10.246600 11.283672
##
## [[4]]
## [1] 11.302173 10.259163 9.387929 9.978455
##
## [[5]]
## [1] 10.914550 10.051102 9.542133 9.265938
##
## [[6]]
## [1] 9.786961 10.662776 10.032204 10.114873
##
## [[7]]
## [1] 10.551356 9.339384 10.968024 9.186852
##
## [[8]]
## [1] 10.705681 9.921886 10.833917 11.543438
##
## [[9]]
## [1] 9.559891 10.493529 8.865914 9.145936
##
## [[10]]
## [1] 9.096407 9.777289 9.559224 8.810655
Şimdi sıra vektörleri rbind
ile satır satır birleştirmeye geldi. Liste elemanlarını topluca data frame altında birleştirebilmek için do.call
fonksiyonunu kullanacağız. do.call
fonksiyonuna ilk parametre olarak herhangi bir fonksiyonu atayabiliriz. Ardından fonksiyona girmesini istediğimiz parametreleri liste olarak verebiliriz. do.call
ilk parametredeki fonksiyonu, ikinci parametredeki nesnelerle çalıştırır. rbind
ile oluşturduğumuz matrisi data.frame
fonksiyonuyla data framee çeviriyoruz:
df2 <- data.frame(do.call(rbind, lst))
df2
## X1 X2 X3 X4
## 1 9.604798 10.781800 9.801167 10.741509
## 2 10.747974 11.614187 9.838524 12.590411
## 3 8.600719 10.340999 10.246600 11.283672
## 4 11.302173 10.259163 9.387929 9.978455
## 5 10.914550 10.051102 9.542133 9.265938
## 6 9.786961 10.662776 10.032204 10.114873
## 7 10.551356 9.339384 10.968024 9.186852
## 8 10.705681 9.921886 10.833917 11.543438
## 9 9.559891 10.493529 8.865914 9.145936
## 10 9.096407 9.777289 9.559224 8.810655
Mevcut bir data frame’e nasıl yeni bir satır eklerim?
Önce elimizdeki yeni veriyi bir data frame’e çevirip sonra rbind
ile iki data frame’i birleştiririz:
(new_vec <- rnorm(4,10,1))
## [1] 10.389983 11.073376 9.485565 10.821270
temp_df <- (new_vec)
df2 <- rbind(df2,temp_df)
df2
## X1 X2 X3 X4
## 1 9.604798 10.781800 9.801167 10.741509
## 2 10.747974 11.614187 9.838524 12.590411
## 3 8.600719 10.340999 10.246600 11.283672
## 4 11.302173 10.259163 9.387929 9.978455
## 5 10.914550 10.051102 9.542133 9.265938
## 6 9.786961 10.662776 10.032204 10.114873
## 7 10.551356 9.339384 10.968024 9.186852
## 8 10.705681 9.921886 10.833917 11.543438
## 9 9.559891 10.493529 8.865914 9.145936
## 10 9.096407 9.777289 9.559224 8.810655
## 11 10.389983 11.073376 9.485565 10.821270
Bu işlem esnasında dikkat edilmesi gereken bir husus şudur; şayet df2
data frame’inin değişkenlerinin kendi atadığımız isimleri olsaydı, eklediğimiz data frame’in değişken isimleri de aynı olmalı idi, aksi halde işlem hatalı olacaktır.
Boş bir data frame oluşturmak istiyorum, nasıl yapabilirim?
Bazen eldeki verileri data frame olarak birleştirmektense, büyüklüğü ve değişken adları belirlenmiş boş bir data frame üretmemiz gerekebilir. Bu şekilde R’ın bellek tahsisi yapmasını dağlayabiliriz. Örneğin dört farklı değişken ve 1000 tane gözlem içeren bir data frame üretelim:
N <- 1000
df3 <- data.frame(id = numeric(N), name = character(N), weight = numeric(N), height = numeric(N))
head(df3,5)
## id name weight height
## 1 0 0 0
## 2 0 0 0
## 3 0 0 0
## 4 0 0 0
## 5 0 0 0
Böylece boş bir data frame ürettik. R, numerik değişkenlere 0 değeri atadı.
Data frame’de bulunan değişkenlerin konumuna göre seçme işlemini nasıl yaparım?
Yukarıda listelere ilişkin olarak söylediğimiz husus data frme için de geçerlidir. Hatırlarsanız liste elemanlarını seçerken, tek köşeli parantez (x[n]
) liste, çift köşeli parantez (x[[n]]
) ve dolar işareti (x$n
) vektör olarak çıktı veriyordu. Aynı biçimde data frame’lerde de tek köşeli parantez (x[n]
) data frame, çift köşeli parantez (x[[n]]
) ve dolar işareti (x$n
) vektör olarak çıktı vermektedir.
Bu genel kural, fakat aşağıda istisnai durumlar gelecek, buna dikkat ederseniz data frame’lerde seçim işlemini öğrenirken daha az acı çekersiniz.
df2[[1]]
## [1] 9.604798 10.747974 8.600719 11.302173 10.914550 9.786961 10.551356
## [8] 10.705681 9.559891 9.096407 10.389983
df2[1]
## X1
## 1 9.604798
## 2 10.747974
## 3 8.600719
## 4 11.302173
## 5 10.914550
## 6 9.786961
## 7 10.551356
## 8 10.705681
## 9 9.559891
## 10 9.096407
## 11 10.389983
df2[,1]
## [1] 9.604798 10.747974 8.600719 11.302173 10.914550 9.786961 10.551356
## [8] 10.705681 9.559891 9.096407 10.389983
Yukarıda df2[[1]]
vektör, df2[1]
data frame ve matris notasyonu kullandığımız df2[,1]
vektör olarak çıktı vermektedir. İllaki data frame istiyorsak bunu df2[,1, drop=FALSE]
ile başarabiliriz (sadece matris notasyonunda).
df2[,1, drop=FALSE]
## X1
## 1 9.604798
## 2 10.747974
## 3 8.600719
## 4 11.302173
## 5 10.914550
## 6 9.786961
## 7 10.551356
## 8 10.705681
## 9 9.559891
## 10 9.096407
## 11 10.389983
Birden fazla sütun seçmek istiyorsak vektör biçiminde çıktı alamayız. Dolayısyla çift köşeli parantez (x[[n]]
) yapısını kullanamayız. Birden fazla değişken seçerken matris notasyonunu kullanmalıyız. Yani, [satır,sütun]
biçiminde yazmalıyız. Satırların tamamını ve belli sütunları seçeceksek, satır değerini boş bırakmalı ve virgülü unutmamalıyız, [,sütun]
şeklinde. Sütunların tamamını ve belli satırları seçeceksek bunun tersini yapmalıyız,[satır,]
. Sütunlar ardışıksa başlangıç:bitiş
şeklinde seri oluşturabilir veya c(sütun, sütun)
seklinde seçim yapabiliriz.
df2[,c(1,3)]
## X1 X3
## 1 9.604798 9.801167
## 2 10.747974 9.838524
## 3 8.600719 10.246600
## 4 11.302173 9.387929
## 5 10.914550 9.542133
## 6 9.786961 10.032204
## 7 10.551356 10.968024
## 8 10.705681 10.833917
## 9 9.559891 8.865914
## 10 9.096407 9.559224
## 11 10.389983 9.485565
df2[1:5,c(1,3)]
## X1 X3
## 1 9.604798 9.801167
## 2 10.747974 9.838524
## 3 8.600719 10.246600
## 4 11.302173 9.387929
## 5 10.914550 9.542133
df2[1:5,]
## X1 X2 X3 X4
## 1 9.604798 10.78180 9.801167 10.741509
## 2 10.747974 11.61419 9.838524 12.590411
## 3 8.600719 10.34100 10.246600 11.283672
## 4 11.302173 10.25916 9.387929 9.978455
## 5 10.914550 10.05110 9.542133 9.265938
Data frame’ler, R’da en sık kullanılan veri yapılarından olduğundan biraz vakit harcayıp bu kuralları anlamak daha sonraki çalışmalarda size zaman kazandıracak ve böylelikle anlaşılmaz hata mesajlarını çözmeye çabalamaktan kurtulup akıl sağlığınızı korumuş olacaksınız.
Data frame sütunlarını sütun (değişken) isimleriyle nasıl seçebilirim?
Data frame sütunlarını sütun (veya değişken) isimleriyle seçerken x[["isim"]]
, x["isim"]
veya x$isim
yapılarından birisini kullanabiliriz. Bir önceki başlık altındaki kurallar burada da geçerli:
colnames(df2) <- c("world","moon","mars","saturn")
# Vektör biçiminde çıktı
df2[["world"]]
## [1] 9.604798 10.747974 8.600719 11.302173 10.914550 9.786961 10.551356
## [8] 10.705681 9.559891 9.096407 10.389983
df2$world
## [1] 9.604798 10.747974 8.600719 11.302173 10.914550 9.786961 10.551356
## [8] 10.705681 9.559891 9.096407 10.389983
df2["world"] # Data frame biçiminde çıktı
## world
## 1 9.604798
## 2 10.747974
## 3 8.600719
## 4 11.302173
## 5 10.914550
## 6 9.786961
## 7 10.551356
## 8 10.705681
## 9 9.559891
## 10 9.096407
## 11 10.389983
Birden fazla sütun seçebiliriz:
df2[c("moon", "world", "mars")] # Data frame biçiminde çıktı
## moon world mars
## 1 10.781800 9.604798 9.801167
## 2 11.614187 10.747974 9.838524
## 3 10.340999 8.600719 10.246600
## 4 10.259163 11.302173 9.387929
## 5 10.051102 10.914550 9.542133
## 6 10.662776 9.786961 10.032204
## 7 9.339384 10.551356 10.968024
## 8 9.921886 10.705681 10.833917
## 9 10.493529 9.559891 8.865914
## 10 9.777289 9.096407 9.559224
## 11 11.073376 10.389983 9.485565
Matris notasyonu kullanabiliriz. Tek sütur seçmemiz halinde vektör biçiminde çıktı alırız. Yukarıdaki gibi drop=FALSE
parametresiyle data frame olarak çıktı alabiliriz:
df2[,"moon"] # Vektör biçiminde çıktı
## [1] 10.781800 11.614187 10.340999 10.259163 10.051102 10.662776 9.339384
## [8] 9.921886 10.493529 9.777289 11.073376
df2[,"moon", drop=FALSE] # Vektör biçiminde çıktı
## moon
## 1 10.781800
## 2 11.614187
## 3 10.340999
## 4 10.259163
## 5 10.051102
## 6 10.662776
## 7 9.339384
## 8 9.921886
## 9 10.493529
## 10 9.777289
## 11 11.073376
Matris notasyonuyla birden fazla satır seçilirse yine vektör şeklinde çıktı gelir. Data frame isteniyorsa drop=FALSE
burada da kullanılabilir:
df2[1:5,"moon"] # Vektör biçiminde çıktı
## [1] 10.78180 11.61419 10.34100 10.25916 10.05110
Matris notasyonuyla birden fazla sütun seçilirse data frame şeklinde çıktı gelir:
df2[1:5, c("moon","saturn")] # Vektör biçiminde çıktı
## moon saturn
## 1 10.78180 10.741509
## 2 11.61419 12.590411
## 3 10.34100 11.283672
## 4 10.25916 9.978455
## 5 10.05110 9.265938
Sütun seçim işlemini daha pratik yapamaz mıyız?
İlk başlayanlar için yukarıda anlatılan seçme işlemleri çok karışık gelebilir. Çok şükür sütun seçim işlemini kolaylaştıracak bir fonksiyon mevcut, subset()
:
subset(df2, select=c(moon,saturn))
## moon saturn
## 1 10.781800 10.741509
## 2 11.614187 12.590411
## 3 10.340999 11.283672
## 4 10.259163 9.978455
## 5 10.051102 9.265938
## 6 10.662776 10.114873
## 7 9.339384 9.186852
## 8 9.921886 11.543438
## 9 10.493529 9.145936
## 10 9.777289 8.810655
## 11 11.073376 10.821270
subset()
ile data frame üzerinde filtreleme de yapabiliriz. Mesela world
değeri 9’dan küçük olan moon
ve saturn
değişkenlerini seçelim:
subset(df2, select=c(moon,saturn), subset = (world < 9))
## moon saturn
## 3 10.341 11.28367
world
değişkeninin ortalamasından büyük olan moon
ve saturn
değişkenlerini seçelim:
subset(df2, select=c(moon,saturn), subset = (moon > mean(world) & saturn > mean(world)))
## moon saturn
## 1 10.78180 10.74151
## 2 11.61419 12.59041
## 3 10.34100 11.28367
## 6 10.66278 10.11487
## 11 11.07338 10.82127
İstemediğimiz bir sütun/sütunları başına (-
) koyarak hariç tutabiliriz:
subset(df2, select=-c(moon,saturn))
## world mars
## 1 9.604798 9.801167
## 2 10.747974 9.838524
## 3 8.600719 10.246600
## 4 11.302173 9.387929
## 5 10.914550 9.542133
## 6 9.786961 10.032204
## 7 10.551356 10.968024
## 8 10.705681 10.833917
## 9 9.559891 8.865914
## 10 9.096407 9.559224
## 11 10.389983 9.485565
Ancak data frame üzerinde daha incelikli seçimler yapabilmek için konuma göre seçim yapma işleminde ustalaşmak gerekmektedir.
Data frame’de bulunan değişken isimlerini nasıl değiştirebilirim?
Data frame oluştururken değişkenlere isim vermezsek, R kendisi isim atamaktadır. colnames
fonksiyonu ile istediğimiz değişken adlarını atayabiliriz:
df4 <- data.frame(matrix(sample(50:100, 30, replace = TRUE),10,3))
colnames(df4) <- c("age","weight","height")
df4
## age weight height
## 1 95 89 83
## 2 79 65 68
## 3 61 83 82
## 4 86 83 67
## 5 97 52 97
## 6 100 63 92
## 7 70 92 57
## 8 65 93 84
## 9 60 90 97
## 10 60 94 92
Data frame’imde NA
değerleri var ve fonksiyonlar hatalı sonuç veriyor, ne yapabilirim?
Verisetinde NA
değerleri olması halinde hesaplama yapan fonksiyonlar çalışmayabilir. Bu durumu bazı fonksiyonlarda bulunan na.rm
parametresini na.rm = TRUE
şeklinde değer atayarak düzeltebiliriz. Önce bir data frame oluşturup, rastgele seçeceğimiz yedi değere NA
atayalım:
df5 <- data.frame(matrix(sample(50:100, 30, replace = TRUE),10,3))
for(i in 1:7){
r <- sample(1:10, 1)
c <- sample(1:3, 1)
df5[r,c] <- NA
}
df5
## X1 X2 X3
## 1 98 NA 84
## 2 59 75 86
## 3 86 NA 86
## 4 NA 67 98
## 5 61 63 59
## 6 76 84 NA
## 7 50 71 69
## 8 NA 93 51
## 9 86 63 NA
## 10 78 92 NA
na.rm
parametresini kullanmayınca sonuçta NA
olarak geliyor:
mean(df5$X1)
## [1] NA
mean(df5$X1, na.rm=TRUE)
## [1] 74.25
Yahut na.omit fonksiyonuyla
, NA
içeren bütün satırları kaldırabiliriz:
colSums(df5)
## X1 X2 X3
## NA NA NA
colSums(na.omit(df5))
## X1 X2 X3
## 170 209 214
İki veya daha fazla data frame’i birleştirmek istiyorum, nasıl yaparım?
İki veya daha fazla data frame’i yan yana yani sütun olarak birleştirmek için cbind
, alt alta yani satır olarak birleştirmek için rbind
kullanabiliriz. Dikkat edilmesi gereken ilk husus rbind
ile sütun adları aynı olmalıdır. Diğer yandan cbind
kullanırken farklı sütun adları olması yeni data frame’de seçim yapma işlemini kolaylaştıracaktır:
df6 <- data.frame(matrix(sample(50:100, 30, replace = TRUE),10,3))
df7 <- data.frame(matrix(sample(50:100, 30, replace = TRUE),10,3))
df8 <- rbind(df6,df7)
colnames(df7) <- c("X4","X5","X6")
df9 <- cbind(df6,df7)
Satır bazında birleştirme yaparken rbind
aynı sayıda sütun (değişken) gerektirmektedir, aksi halde hata verecektir. Sütun bazında birleştirme yaparken aynı sayıda satır olmaması durumunda cbind
yine de birleştirme işlemini yapacaktır. Ancak küçük sütunları R’ın recycling kuralı uyarınca kendisi dolduracaktır. Dolayısıyla böyle bir durumda beklediğiniz çıktıyı alamayabilirsiniz.