👩🏻‍💻 Ödev 3: Veri Görselleştirme

🎯 Ödevin Amacı

Bu ödevin amacı, R ortamında veri görselleştirme becerileri geliştirmek, farklı türde grafikler üretmek ve veriyi anlamlı biçimde sunabilmektir.

1. Kaynaklardan Öğrendiklerim

Okumalarımdan aldığım notlar son derste öğrendiklerimin de etkisiyle veri görselleştirme üzerinde yoğunlaşıyor. R’ın görselleştirme paketlerinden olan ve grafiklerin grameri olarak bilinen ggplot2 ile katman katman grafik oluşturmak mümkün. Üstelik bu grafikler işlevinin yanı sıra son derece estetik bir görünüme de sahip olabilir. Kullanılacak veri setini ve değişkenlerin hangi rolü üstleneceğini belirledikten sonra, veriyi nasıl görselleştireceğimizi (geom) ile ekliyoruz. Saçılım grafiği yapmak istersek geom_point() veya kutu grafiği yapmak istersek geom_boxplot() ekliyoruz. Üzerine eklemek istediğimiz herhangi bir işlem için + operatörünü kullanıyoruz. Örneğin bir saçılım grafiğinin üzerine bir regresyon çizgisi geom_smooth() ekleyebiliriz.

Bir parametreyi aes() fonksiyonu içine yazdığımızda (aes(color = CINSIYET) gibi), ggplot2’ye o estetiği veri setimizdeki bir değişkene bağlamasını söylemiş oluyoruz. Bunun sonucunda ggplot2, CINSIYET sütunundaki farklı değerler için otomatik olarak farklı renkler atıyor; böylece grafikteki ‘Kız’ noktaları mor, ‘Erkek’ noktaları ise yeşil oluyorr. Aynı parametreyi aes() dışında, doğrudan geom fonksiyonunun içine yazdığımızda (geom_point(color = "purple") gibi), o estetiğe sabit bir değer atamış oluruz. Bu durumda verideki değerler ne olursa olsun, tüm noktalar, cinsiyetten bağımsız mor renkte çiziliyor.

facet veri setini alt gruplara ayırarak çoklu panellerden oluşan bir matris oluşturmamızı sağlıyor. Farklı alt gruplar arasındaki örüntüleri görsel olarak karşılaştırmayı kolaylaştırıyor.

Büyük veri setleriyle çalışırken saçılım grafiklerinde karşılaştığımız overplotting sorunu verinin gerçek dağılımını ve yoğunluğunu görmeyi oldukça zorlaştırırken; bu sorunu çözmek için geom_point() fonksiyonu içinde position = "jitter" argümanını kullandığımızda, ggplot2 her bir noktanın konumuna çok küçük ve rastgele bir kaydırma ekliyor. Bu işlem üst üste binen noktaları birbirinden ayırarak dağıtıyor ve böylece verinin yoğun olduğu bölgeleri net bir şekilde ortaya çıkarıyor. Çubuk grafiklerini yan yana karşılaştırmak için position = "dodge" veya alan grafiklerini üst üste yığmak için position = "stack" gibi diğer ayarları kullanarak farklı geom’ların davranışını kontrol edebiliriz.

“Etkili bir görselleştirme genellikle iyi hazırlanmış bir veri setiyle başlar. Amacımıza uygun ilgili değişkenleri içerecek şekilde veriyi düzenledikten sonraki önemli diğer aşama… veri görselleştirmedir.” Bazen ham veriyi doğrudan grafiğe dökmek yerine önce onu özetlememiz gerekir. Örneğin kategorilere göre ortalamaları hesaplayıp bunları bir sütun grafiği ile göstermek isteyebiliriz. İşte bu noktada modern tidyverse pratikleri devreye giriyor. summarise_at(), summarise_if() gibi _at, _if, _all uzantılı dplyr fonksiyonları artık kullanımdan kaldırılmış (deprecated) olarak kabul ediliyor. Bu fonksiyonların modern ve çok daha esnek alternatifi, across() fonksiyonu. across(), summarise() veya mutate() gibi dplyr fiilleri içinde, birden çok sütuna aynı işlemi (örneğin ortalama veya standart sapma hesaplama) uygulamak için kullanılan standart yöntemdir. Bu, görselleştirme öncesi veri hazırlama adımını oldukça temiz ve okunabilir hale getiriyor. Son olarak mutate() fonksiyonu ile veri setine yeni değişkenler eklenirken mevcut değişkenler de korunur ancak transmute() fonksiyonu ile eski değişkenler veri setiden çıkarılarak yeni değişken eklenir.

2. Uygulama Görevi: Grafik Oluşturma

🔹 Adım 1: Veri seçimi

Öncelikle hazır veri setlerinden -palmerpenguins, gapminder, nycflights13, babynames veya ggplot2::mpg- olan gapminder veri seti kullanılmaya karar verilmiştir. Bu veri seti 1952–2007 yılları arasında ülkelerin yaşam süresi, kişi başı gelir ve nüfus bilgilerini içermektedir.

📍 paketlerin etkinleştirilmesi

Veri setinin yer aldığı paket de dahil olmak üzere gapminder, dplyr ve ggplot2 paketleri etkinleştirilmiştir.

library(gapminder)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)

gm <- gapminder

📍veri paketini aktarma ve inceleme

# gapminder veri setini R ortamına aktarma
data("gapminder")

gm_2007 <- gapminder

# Veri setinin yapısını inceleme
glimpse(gm_2007)
## Rows: 1,704
## Columns: 6
## $ country   <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", …
## $ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, …
## $ year      <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, …
## $ lifeExp   <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.8…
## $ pop       <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12…
## $ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, …

Veri setinde 142 ülke, 5 kıta ve 1952–2007 yılları arasında 12 farklı yıl gözlemi yer almaktadır. Toplam 1.704 satır ve 6 değişken içerir. Değişkenler: ülke adı (country), kıta (continent), yıl (year), yaşam beklentisi (lifeExp), nüfus (pop), ve kişi başı gelir (gdpPercap) olarak ifade edilebilir.

📍 grafiklerin seçilmesi

Grafik 1: Gelir–Yaşam Süresi (geom_point)

Grafik 2: Kıtalara Göre Ülke Sayısı (geom_col)

Grafik 3: Kıtalara Göre Gelir Dağılımı (geom_boxplot)

Grafik 4: Yaşam Süresi Dağılımları (geom_density + facet)

Grafik 5: Kıtaların Zaman İçinde Ortalama Yaşam Süresi (geom_line)

🔹 Adım 2: Grafikleri Oluşturma

Bu bölümde, gapminder veri setinden yararlanılarak oluşturulan beş farklı grafik yer almaktadır. Her grafik, veri setindeki farklı bir ilişkiyi ya da dağılım biçimini temsil edecek şekilde seçilmiş, uygun geom_*() fonksiyonlarıyla görselleştirilmiştir.

📍Grafik 1: Gelir–Yaşam Süresi

ggplot(gm_2007, aes(x = gdpPercap, y = lifeExp)) +
  geom_point(aes(color = continent, size = pop), alpha = 0.5) +
  scale_x_log10(labels = scales::label_number(scale_cut = scales::cut_si(" "))) +
  scale_size(range = c(1.5, 5), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(
    title = "2007: Kişi Başı Gelir (log) ve Yaşam Süresi",
    subtitle = "Renk: Kıta • Nokta boyutu: Nüfus",
    x = "Kişi Başı Gelir (log ölçek)",
    y = "Beklenen Yaşam Süresi",
    color = "Kıta",
    caption = "Kaynak: gapminder"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    text = element_text(family = "times"),
    axis.title.x = element_text(margin = margin(t = 12)),
    axis.title.y = element_text(margin = margin(r = 12)),
    plot.title = element_text(size = 12, face = "bold", margin = margin(b = 8)),
    plot.subtitle = element_text(size = 11, margin = margin(b = 9)),
    plot.caption = element_text(size = 9, color = "gray50", hjust = 1)
  )

📍Grafik 2: Kıtalara Göre Ülke Sayısı

countries_2007 <- gm %>%
  filter(year == 2007) %>%
  distinct(continent, country) %>%
  count(continent)

ggplot(countries_2007, aes(x = reorder(continent, n), y = n, fill = continent)) +
  geom_col(width = 0.7, color = "gray40", linewidth = 0.5) +
  coord_flip() +
  scale_fill_brewer(palette = "Pastel1") +
  labs(
    title = "2007: Kıtaya Göre Ülke Sayısı",
    subtitle = "Her sütun, gapminder verisindeki gözlenen ülke sayısını göstermektedir.",
    x = "Kıta",
    y = "Ülke Sayısı",
    fill = "Kıta",
    caption = "Kaynak: gapminder (2007 verisi)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    text = element_text(family = "Times"),                   # yazı tipi
    plot.title = element_text(size = 12, face = "bold", margin = margin(b = 8)),
    plot.subtitle = element_text(size = 12, margin = margin(b = 10)),
    axis.title.x = element_text(margin = margin(t = 12)),    # eksen boşlukları
    axis.title.y = element_text(margin = margin(r = 12)),
    axis.text = element_text(size = 11),
    legend.position = "none",
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_line(color = "gray80", linetype = "dotted"),
    panel.grid.major.y = element_blank()
  )

📍Grafik 3: Kıtalara Göre Gelir Dağılımı

ggplot(gm_2007, aes(x = continent, y = gdpPercap, fill = continent)) +
  geom_boxplot(outlier.alpha = 0.6, color = "gray40") +
  scale_y_log10(labels = scales::label_number(scale_cut = scales::cut_si(" "))) +
  scale_fill_brewer(palette = "Pastel2") +
  labs(
    title = "2007: Kıtalar Arası Kişi Başı Gelir Dağılımı",
    subtitle = "Her kutu, ilgili kıtadaki gelir dağılımını göstermektedir.",
    x = "Kıta",
    y = "Kişi Başı Gelir (log ölçek)",
    fill = "Kıta",
    caption = "Kaynak: gapminder (2007 verisi)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    text = element_text(family = "Times"),                # yazı tipi
    plot.title = element_text(size = 12, face = "bold", margin = margin(b = 8)),
    plot.subtitle = element_text(size = 12, margin = margin(b = 10)),
    axis.title.x = element_text(margin = margin(t = 12)), # eksen boşlukları
    axis.title.y = element_text(margin = margin(r = 12)),
    axis.text = element_text(size = 11),
    legend.position = "none",
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_line(color = "gray85", linetype = "dotted"),
    panel.grid.major.y = element_line(color = "gray85", linetype = "dotted")
  )

📍Grafik 4: Yaşam Süresi Dağılımları

ggplot(gm_2007, aes(x = lifeExp, fill = continent)) +
  geom_density(alpha = 0.6, color = "gray40") +
  facet_wrap(~ continent, ncol = 3) +
  scale_fill_brewer(palette = "Pastel1") +
  labs(
    title = "2007: Kıtalar Bazında Yaşam Süresi Dağılımları",
    subtitle = "Her panel ilgili kıtadaki yaşam süresi dağılımını göstermektedir.",
    x = "Beklenen Yaşam Süresi (yıl)",
    y = "Yoğunluk",
    fill = "Kıta",
    caption = "Kaynak: gapminder (2007 verisi)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    text = element_text(family = "Times"),               # yazı tipi
    plot.title = element_text(size = 12, face = "bold", margin = margin(b = 8)),
    plot.subtitle = element_text(size = 12, margin = margin(b = 10)),
    axis.title.x = element_text(margin = margin(t = 12)),
    axis.title.y = element_text(margin = margin(r = 12)),
    axis.text = element_text(size = 11),
    strip.text = element_text(size = 12, face = "bold"), # facet başlıkları
    legend.position = "none",                            # legend gizlendi
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_line(color = "gray85", linetype = "dotted"),
    panel.grid.major.y = element_line(color = "gray85", linetype = "dotted"),
    panel.spacing = unit(1, "lines")                     # facetler arası boşluk
  )

📍Grafik 5: Kıtaların Zaman İçinde Ortalama Yaşam Süresi

trend <- gm %>%
  group_by(continent, year) %>%
  summarise(mean_life = mean(lifeExp), .groups = "drop")

ggplot(trend, aes(x = year, y = mean_life, color = continent)) +
  geom_line(linewidth = 1.1) +
  geom_vline(xintercept = 2000, linetype = "dashed", color = "gray40") +
  annotate("text", x = 2000, y = 37, label = "2000", angle = 90, vjust = -0.5, size = 3.2, family = "Times") +
  scale_color_brewer(palette = "Set2") +
  labs(
    title = "1952–2007: Kıtaların Ortalama Yaşam Süresi Eğilimleri",
    subtitle = "Dikey çizgi referans yıl olarak 2000’i göstermektedir.",
    x = "Yıl",
    y = "Ortalama Beklenen Yaşam Süresi",
    color = "Kıta",
    caption = "Kaynak: gapminder (1952–2007)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    text = element_text(family = "Times"),                  # yazı tipi
    plot.title = element_text(size = 12, face = "bold", margin = margin(b = 8)),
    plot.subtitle = element_text(size = 12, margin = margin(b = 10)),
    axis.title.x = element_text(margin = margin(t = 12)),   # eksen boşlukları
    axis.title.y = element_text(margin = margin(r = 12)),
    axis.text = element_text(size = 11),
    legend.position = "bottom",
    legend.title = element_text(size = 11),
    legend.text = element_text(size = 10),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_line(color = "gray85", linetype = "dotted"),
    panel.grid.major.y = element_line(color = "gray85", linetype = "dotted")
  )

🔹 Adım 3: Grafiklere İlişkin Yorum Ekleme

Bu bölümde önceki bölümde oluşturulan her grafik için görselleştirmenin amacı, veriden elde edilen temel bulgular ve alternatif sunum biçimlerine ilişkin kısa yorumlara yer verilmiştir.

Grafik 1: Gelir–Yaşam Süresi

📌 Bu grafik kişi başı gelir düzeyi ile beklenen yaşam süresi arasındaki ilişkiyi incelemek amacıyla oluşturulmuştur. İki sayısal değişkenin birlikte gösterilmesi, ekonomik refahın yaşam süresine etkisini görselleştirmeyi hedeflemektedir.

📌 Grafik 1’de 2007 yılı verilerine göre gelir düzeyi arttıkça yaşam süresinin de yükseldiği, dolayısıyla değişkenler arasında pozitif yönlü bir ilişkinin bulunduğu görülmektedir. Afrika ülkeleri düşük gelir ve düşük yaşam süresiyle kümelenirken, Avrupa ve Okyanusya ülkeleri daha yüksek değerlerde toplanmaktadır.

📌 İlişkiyi daha net görmek için bir regresyon çizgisi (geom_smooth(method = "lm")) eklenebilir veya zaman değişkeni de dahil edilerek hareketli bir animasyon (örneğin gganimate paketiyle) oluşturulabilir.

Grafik 2: Kıtalara Göre Ülke Sayısı

📌 Bu grafik, gapminder veri setinde yer alan ülkelerin kıtalara göre dağılımını göstermek için hazırlanmıştır.

📌 2007 yılı itibarıyla veri setinde en fazla ülke Asya’da, en az ülke ise Okyanusya’da yer almaktadır. Bu durum, sonraki analizlerde Asya’nın veri ağırlığını artırırken, Okyanusya’nın temsil gücünü sınırladığını düşündürmektedir.

📌 Sütun grafiği yerine aynı bilginin pasta grafiği (geom_bar(width = 1, stat = "count") + coord_polar()) biçiminde gösterimi veya dünya haritası (geom_map) üzerinde bölgesel renklendirme ile sunumu yapılabilir.

Grafik 3: Kıtalara Göre Gelir Dağılımı

📌 Bu grafik farklı kıtalarda kişi başı gelir dağılımlarını karşılaştırmak ve gruplar arasındaki merkezi eğilimler ve yayılım farklarını incelemek için tasarlanmıştır.

📌 Logaritmik ölçekte gösterilen kutu grafiği, Avrupa ve Amerika kıtalarının gelir açısından daha yüksek ortanca değerlere sahip olduğunu ortaya koymaktadır. Afrika kıtasında gelir dağılımı oldukça geniştir ve uç değerler fazladır.

📌 Kutu grafiği yerine violin grafiği (geom_violin()) kullanılarak dağılımın yoğunluğu daha ayrıntılı biçimde gösterilebilir veya her ülke bir nokta olarak eklenerek (geom_jitter()) varyasyon artırılabilir.

Grafik 4: Yaşam Süresi Dağılımları

📌 Bu grafik yaşam süresinin kıtalara göre dağılım biçimini göstermek ve bölgeler arasındaki yoğunluk farklılıklarını ortaya çıkarmak amacıyla hazırlanmıştır. Facet kullanımı her kıtanın dağılımını ayrı ayrı değerlendirilebilir hale getirir.

📌 Avrupa ve Okyanusya panellerinde dağılımın dar ve yüksek yaşam süresi etrafında yoğunlaştığı; Afrika’da ise daha geniş bir aralıkta düşük ortalamalarla yayıldığı görülmektedir. Bu durum kıtalar arasındaki sağlık ve yaşam standartı farklılıklarını yansıtır.

📌 Tüm kıtalar tek panelde birleştirilip renk ayrımıyla (aes(fill = continent)) gösterilerek genel eğilimler vurgulanabilir ya da histogram biçiminde (geom_histogram()) daha sayısal bir dağılım görünümü elde edilebilir.

Grafik 5: Kıtaların Zaman İçinde Ortalama Yaşam Süresi

📌 Bu grafik 1952–2007 yılları arasında kıtaların ortalama yaşam süresi eğilimlerini zaman serisi olarak izlemek amacıyla hazırlanmıştır. Zaman boyutunun eklenmesi değişimin yönünü ve hızını görselleştirmeye olanak tanır.

📌 Tüm kıtalarda yaşam süresi dönem boyunca artış eğilimi göstermektedir. Avrupa ve Okyanusya en yüksek değerlere ulaşırken, Afrika kıtası düşük seviyelerden başlamakla birlikte 2000 sonrası dönemde belirgin bir yükseliş sergilemiştir. Dikey çizgiyle vurgulanan 2000 yılı, küresel sağlık ve kalkınma göstergelerinde dönüm noktası niteliğindedir.

📌 Zaman serisi, kıta bazında facet’lenmiş küçük grafikler biçiminde (facet_wrap(~continent)) veya hareketli bir zaman çizelgesi olarak (gganimate paketiyle) sunularak eğilimlerin dinamik görünümü güçlendirilebilir.

3. RMarkdown Günlüğüm

Bu hafta derste veri görselleştirmenin temel bileşenlerini öğrendim. Grafik çizmeden önce veriyi hazırlamak, dönüştürmek ve temizlemek gibi ön adımların görselleştirmenin kalitesini doğrudan etkilediğini fark ettim. Veri setlerinin etiketli (labelled) değişkenler içerebileceğini ve bu değişkenlerin analiz sürecinde hata üretebileceğini öğrendik. Bu durumu düzeltmek için haven ve sjlabelled paketlerini kullanarak değişkenleri faktör yapısına dönüştürdük. Eksik verileri incelemek ve temizlemek için colSums(is.na()) ve na.omit() fonksiyonlarını kullandım. Bir noktada %>% operatörünün çalışmadığı bir durumda arkadaşımın önerisiyle library(magrittr) paketini yüklemem gerektiğini öğrendim ve hemen not aldım. Çubuk grafikleri oluştururken geom_bar() fonksiyonunun varsayılan olarak sayım (count) yaptığını, farklı kategorileri karşılaştırmak için position = "dodge" ya da oranlarını görmek için position = "fill" argümanlarını ekleyebildiğimi öğrendim. Bu sayede aynı veri kümesini farklı perspektiflerle görselleştirebileceğimi fark ettim. Elbette bunları buraya yazdığım kadar kolay yapamadığım için tekrar tekrar pratik etmek gerekiyor. Histogram ve yoğunluk grafikleri (density plots) üzerinde çalışırken, bins ve binwidth argümanlarının çubuk sayısını doğrudan etkilediğini gözlemledim. geom_vline() ile ortalama değerleri göstermek hem görseli açıklayıcı hale getirdi hem de istatistiksel yorum yapmayı kolaylaştırdı. Bu süreçte facet_wrap() kullanarak grafikleri alt panellere ayırmanın karşılaştırmaları çok daha anlaşılır kıldığını fark ettim. geom_text() fonksiyonunu kullanarak grafiğe metin eklemeyi ve vjust ile hjust ayarlarının metinlerin konumunu kontrol ettiğini denedim. Çok daha fazlasını öğrenmek ve yapmak için heyecanlıyım.