Bölüm 8 Faktorler

Faktörler kategorik verilerle uğraşırken kullandığımız verilerdir. Yani değişkenimiz sadece belli bir set içinden değer alabilir.

Faktör oluşturmak için factor() fonksiyonunu kullanabiliriz. Diyelim ki sadece elma, armut, ya da muz olabilen bir verimiz olsun.

a <-  c("elma", "muz", "elma", "armut", "muz")
a
## [1] "elma"  "muz"   "elma"  "armut" "muz"
a_f <- factor(a)
a_f
## [1] elma  muz   elma  armut muz  
## Levels: armut elma muz

Burada a ve a_f objeleri bir kaç açıcan birbirinden farklı. Değerler aynı gibi görülebilir ancak a objemiz bir karakter objesidir. a_f ise bir faktör objesidir ve karşılık aldığı değerler karakter değil, alabileceği kategorik değişkenlerin sayısıdır. Bunu daha iyi anlamak açısından:

as.numeric(a)
## Warning: NAs introduced by coercion
## [1] NA NA NA NA NA

Bu karakterleri nümerik tipe dönüştürmek mümkün olmadığından NA’lardan oluşan bir vektör elde ediyoruz. Aynısını a_f’ye yapalım:

a_f
## [1] elma  muz   elma  armut muz  
## Levels: armut elma muz
as.numeric(a_f)
## [1] 2 3 2 1 3

Şimdi NA yerine sayılar aldık. Bu sayılar da değerlerin faktörün alabileceği değerler arasından kaçıncı olduğuna denk geliyor. a_f’nin “levels” yani alabileceği değerler sırasıyla armut, elma, muz olduğundan, armut 1, elma 2, muz ise 3 oluyor. Burada değerlerin sıralaması varsayılan olarak alfabetik olarak yapılıyor. Ancak bunu değiştirmemiz mümkün:

a_f <- factor(a, levels = c("elma","armut", "muz"))
a_f
## [1] elma  muz   elma  armut muz  
## Levels: elma armut muz
as.numeric(a_f)
## [1] 1 3 1 2 3

Karakterlerle çalışırken faktörleri anlamak görece daha kolay olabilir. Ancak özellikle nümerik kategorilerimiz varsa, objenin faktör olduğunu farketmemek analizimizi çok kötü bir çıkmaza götürebilir ve en sık yapılan hatalardan biridir.

a <- c(1, 2, 5, 10)
a_f <- factor(a)

Şimdi 30u a ve a_f vektörüne böldüğümüzde karşımıza ne çıkıyor bakalım:

30/as.numeric(a)
## [1] 30 15  6  3
30/as.numeric(a_f)
## [1] 30.0 15.0 10.0  7.5

Gördüğünüz gibi a_f’deki değerler nümerik hale dönüştürüldüğünde kendi nümerik değerlerini değil 1,2,3 ve 4 değerlerini aldığından işlem yanlış oldu. Bu özellikle R’a csv ya da excel dosyasından veri okunduğunda karşılaşılan bir problem.

Peki diyelim ki yanlışlıkla nümerik verimizi a_f gibi, faktör olarak okuduk. Bundan geri dönüş yok mu? Veriyi önce karakter sonra nümerik olarak alırsak sorun ortadan kalkıyor:

a_f
## [1] 1  2  5  10
## Levels: 1 2 5 10
as.character(a_f)
## [1] "1"  "2"  "5"  "10"
as.numeric(as.character(a_f))
## [1]  1  2  5 10
30 / a 
## [1] 30 15  6  3
30 / as.numeric(as.character(a_f))
## [1] 30 15  6  3

Gördüğünüz gibi aynı sonucu aldık. Diğer bir çözüm de değerleri alabilecekleri seviyeleri kullanarak gerçek değerleri haline getirerek olabilir:

levels(a_f)
## [1] "1"  "2"  "5"  "10"
30 / as.numeric(levels(a_f)[a_f])
## [1] 30 15  6  3

Birebir bize çok yansımasa da faktörün en büyük yararı verinin depolanmasıyla ilgili. Diyelim ki elimizde 1 milyon kişinin doğduğu ay bilgisi var. Bunu karakter olarak kaydetmek yerine faktör olarak kaydedersek sadece her birey için 1den 12ye kadar birer sayı kaydedilir ve bir de bu sayıların karşılık geldiği değerler. Bu bütün ayların bütün karakterleriyle tek tek yazılmasından oldukça verimli bir çözümdür. read.table’ın değişkenleri faktör olarak okuma eğilimi de bundan kaynaklıdır.

Diğer önemli bir detay da faktör’e c() fonskiyonu ile yeni bir değer eklemekle ilgili. Bunu yapamayız:

a_f
## [1] 1  2  5  10
## Levels: 1 2 5 10
c(a_f, 8)
## [1] 1 2 3 4 8
c(a_f, "armut")
## [1] "1"     "2"     "3"     "4"     "armut"

Gördüğünüz gibi aynı as.numeric() fonksiyonunda karşılaştığımız gibi tüm değerler sıralamaya yani 1, 2, 3, ve 4e dönüştürülüp sonradan ekleme yapılıyor. Peki faktör vektörüne yeni değer ekleyemez miyiz?

factor(c(as.numeric(as.character(a_f)),8))
## [1] 1  2  5  10 8 
## Levels: 1 2 5 8 10

Genel olarak yapmak istediğinizi yapacak hale getirmeniz mümkün ama özellikle tidyverse’te forcats paketini kullanmıyorsanız, çok da gerekli olmadıkça, özellikle başlangıç seviyesindeyken faktörlerden uzak durup, karakter ve nümerik verilerle çalışmanızı tavsiye ederim. Bu faktörler yararlı olmadığından değil, alışkın olana kadar çalışması zor olduğundan. Faktörlerin özellikle yararlı olduğu bir kaç kullanım:

1) Modelleme: Faktörlerin en yaygın kullanımı modelleme yaparken karşımıza çıkıyor. Değişkenleri sürekli değişkenler olarak değil de faktör olarak kaydettiğimizde, modelde doğru şekilde yer almasını sağlayabiliyoruz. Ayrıca çoğu model fonksiyonları karakter vektörü aldıklarında çalışmayabiliyor.

2)table fonksiyonu ile kullanım: Diyelim ki 5 değer alabilen bir değişkeniniz var. Ama elinizdeki örneklem bu 5 değerin sadece 3ünü içeriyor. table() fonksiyonunu kullanarak her değerin kaç kez geçtiğini özetleyebilirsiniz ancak eğer faktörse bu özet 5 değerin tümünü içerirken, karakter ya da nümerik olduğunda 3 değer içerir:

a <-  c("elma", "muz", "elma", "armut", "muz")
table(a)
## a
## armut  elma   muz 
##     1     2     2
a_f <- factor(a, levels = c("elma","muz","armut","karpuz","çilek"))
table(a_f)
## a_f
##   elma    muz  armut karpuz  çilek 
##      2      2      1      0      0

Bu özellik kimi zaman kullanışlı olabilir.

3) Büyük veri ile çalışırken: Daha önce de bahsettiğim gibi faktörler özellikle büyük veri ile çalışırken tekrarlı veri söz konusu ile ciddi yer kazancı sağlamanız anlamına gelebilir.