knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)
options(digits=3)
library(openintro)
library(tidyverse)
library(dplyr)
?runif
#runif in r si randomın r sidir.
runif(10, 0, 1)
## [1] 0.38466 0.68324 0.64880 0.04190 0.00503 0.36791 0.99170 0.23110 0.03482
## [10] 0.37382
runif(100,50,60)
## [1] 52.1 58.9 52.6 50.3 51.4 58.9 50.0 53.0 59.8 55.2 53.1 55.1 55.3 54.9 57.0
## [16] 56.5 57.5 56.3 58.1 55.6 51.2 53.3 59.2 54.7 59.0 54.9 56.0 54.4 59.3 51.7
## [31] 53.5 58.0 58.2 59.8 54.4 51.9 57.6 59.8 58.9 56.1 55.8 57.5 51.8 50.2 50.7
## [46] 57.8 58.6 54.0 54.2 52.7 55.7 57.3 54.3 59.6 51.9 59.1 51.2 57.4 53.2 58.8
## [61] 51.8 54.1 50.6 59.5 52.3 56.0 50.2 52.9 53.3 59.8 54.7 55.0 56.4 51.2 52.1
## [76] 50.4 51.1 53.1 57.1 51.7 52.8 54.3 51.8 51.8 56.1 57.3 56.1 58.6 55.9 53.5
## [91] 57.5 58.3 52.4 51.7 51.1 55.6 53.4 59.1 53.2 54.9
hist(runif(100,50,60))
#tek düze dağılım ürettim minimum 50, maksimum 60 olan 100 sayı üretti
lapply(1:4, runif)
## [[1]]
## [1] 0.679
##
## [[2]]
## [1] 0.132 0.635
##
## [[3]]
## [1] 0.783 0.489 0.491
##
## [[4]]
## [1] 0.563 0.322 0.067 0.712
lapply(5:10, runif,min=10, max=20)
## [[1]]
## [1] 12.0 12.0 15.2 17.5 14.2
##
## [[2]]
## [1] 10.1 17.5 16.0 18.5 19.5 18.6
##
## [[3]]
## [1] 14.5 14.5 18.7 16.4 10.6 15.0 10.7
##
## [[4]]
## [1] 13.9 10.3 16.5 19.6 11.6 11.0 12.0 13.8
##
## [[5]]
## [1] 11.6 14.5 19.8 19.7 17.8 10.0 14.5 10.8 19.1
##
## [[6]]
## [1] 17.9 15.2 15.4 12.6 16.2 12.2 17.3 18.4 13.8 11.4
lapply(1:3, runif, min=1:3, max=10:20)
## [[1]]
## [1] 3.3
##
## [[2]]
## [1] 1.59 5.69
##
## [[3]]
## [1] 5.11 2.55 6.61
lapply(1:3, runif, min=1:3, max=10:20) %>%
lapply(round, 1)
## [[1]]
## [1] 1.3
##
## [[2]]
## [1] 6.2 6.2
##
## [[3]]
## [1] 7.1 7.4 4.4
#pipe + lapply(round, n) yapınca da setup chunka options(digits=n) yapmak da bütün verileri yuvarlar.
set.seed(40)
liste <- list(m1 = matrix(runif(10, 5, 10), 2, 5),
m2 = matrix(runif(20, 10, 20), 4, 5))
liste
## $m1
## [,1] [,2] [,3] [,4] [,5]
## [1,] 8.42 8.45 5.98 6.02 6.87
## [2,] 9.36 5.58 7.31 7.95 5.71
##
## $m2
## [,1] [,2] [,3] [,4] [,5]
## [1,] 11.0 19.6 11.0 11.1 13.1
## [2,] 17.0 18.0 15.8 15.7 16.9
## [3,] 10.8 13.9 14.7 17.9 16.7
## [4,] 12.3 19.8 13.0 16.4 17.6
lapply(liste, function(a){a[,1]*a[,5]})
## $m1
## [1] 57.8 53.4
##
## $m2
## [1] 144 288 180 217
#function ama isimsiz. burada a aslında listeyi refere ediyor, 1. ve 5. sayıları çarpıyor
#sapply aslında daha işlevsel çünkü data çıkartır ama data.frame aynı olması lazım yani sütun ve satır sayısı aynı olmalı
#Kübra hoca lapply kullanıp pipe ile bağlayıp as.dataframe yaparak da oluyorsa sapply ın yaptığını yaptırabiliyormuş
Bu hafta R dersinde apply ailesine ait temel fonksiyonları öğrendim. Genel olarak bu fonksiyonların veri analizi sürecini hızlandıran, kodu kısaltan ve daha düzenli hâle getiren oldukça kullanışlı bir yapı sunduğunudüşünüyorum.
Apply ailesinde hangi fonksiyonun hangi veri yapısıyla (vektör, liste, matris, data frame) çalıştığını ayırt etmenin önemli olduğunu fark ettim.
lapply(List, Fonksiyon) yapısında girdinin liste ya da vektör olabildiğini ve çıktının her zaman liste olduğunu netleştirdim.
Sonucun yapısının bozulmamasını ve garantili şekilde liste dönmesini istediğim durumlarda lapply kullanmanın daha güvenli olduğunu düşünüyorum.
Örneğin basit bir liste için denemem:
veri <- list(A = c(1, 2, 3),
B = c(4, 5, 6))
lapply(veri, mean)
## $A
## [1] 2
##
## $B
## [1] 5
sapply(List, Fonksiyon) fonksiyonunun lapply ile aynı işlemleri yaptığını, ancak çıktıyı mümkün olduğunca sadeleştirmeye çalıştığını fark ettim.
Çıktıyı vektör ya da matris olarak görmek istediğimde sapply daha okunabilir sonuçlar sunuyor, ancak her zaman beklenen formatta dönmeyebileceği için dikkatli kullanılmalı.
Denemem:
sapply(veri, mean)
## A B
## 2 5
apply() fonksiyonunun matrisler üzerinde çalıştığını ve satır ya da sütun bazlı işlemleri kolaylaştırdığını öğrendim.
MARGIN = 1 satırları, MARGIN = 2 ise
sütunları temsil ediyor.
Denemem:
m <- matrix(1:9, nrow = 3)
apply(m, 1, mean)
## [1] 4 5 6
apply(m, 2, mean)
## [1] 2 5 8
Denemem:
rowMeans(m)
## [1] 4 5 6
colMeans(m)
## [1] 2 5 8
Grup bazlı analizlerde tapply, split ve by fonksiyonlarının önemli bir yer tuttuğunu fark ettim. Bu fonksiyonlar sayesinde veriyi kategorilere ayırarak özet istatistikler almak oldukça kolaylaşıyor. Yine de alışkanlıktandır elim ilk group by’a gidiyor hep ilk…
split(Veri, Grup) fonksiyonunun doğrudan hesaplama yapmadığını, sadece veriyi gruplara ayırdığını ve genellikle lapply ile birlikte kullanıldığında daha esnek analizler sunduğunu gördüm.
tapply(Veri, Grup, Fonksiyon) yapısının, bir vektörü gruplara bölüp her grup için ayrı işlem yapmaya olanak sağladığını anladım.
puan <- c(60, 70, 80, 90)
grup <- c("A", "A", "B", "B")
tapply(puan, grup, mean)
## A B
## 65 85
split(puan, grup)
## $A
## [1] 60 70
##
## $B
## [1] 80 90
lapply(split(puan, grup), mean)
## $A
## [1] 65
##
## $B
## [1] 85
mapply(Fonksiyon, Liste1, Liste2, …) fonksiyonunun birden fazla listeyi aynı anda fonksiyona sokarak paralel işlem yaptığını öğrendim.
Mantığını genel olarak kavrasam da, özellikle rep yapıları ve çoklu argüman kullanımı bu kısmı benim için biraz karışık geldi.
vize <- c(60, 70, 80)
final <- c(70, 80, 90)
mapply(function(x, y) 0.4*x + 0.6*y, vize, final)
## [1] 66 76 86
Anonim fonksiyonların, sadece o an apply ailesi içinde kullanılıp atılan geçici fonksiyonlar olduğunu ve küçük işlemler için kodu sadeleştirdiğini öğrendim.
lapply(veri, function(x) x[1])
## $A
## [1] 1
##
## $B
## [1] 4
Vectorize() fonksiyonunun, normalde tek değerle çalışan fonksiyonları vektörlerle çalışabilir hâle getirdiğini anladım; ancak bu yapının arka plan mantığını henüz tam olarak oturtamadım.
Apply ailesinin, R’da daha kısa, daha temiz ve daha okunabilir kod yazmayı sağladığını düşünüyorum. Özellikle mapply ve vectorize konularında daha fazla pratik yapmam gerektiğini fark ettim.