Şu ana kadar yaptığımız analizler genel olarak sayıların dönüşümü üstüne odaklandı. Sayıları nasıl çarpar böler, birbirine ekleyerek yeni değişken oluştururuz konularını öğrenmiştik. Burada ise yine sıkça kullanılan bir veri tipi olan stringler üstünde ne gibi işlemler yapabileceğimizi öğrenecez. Bunu öğrenmek string verileri beklenmedik formatlarda geldiği zaman veya string değişkenlerinin içinden bir kısmı çıkartmak istediğimiz zaman işimize yarayacaktır.
String oluştururken hem “” hem de ’’ yollarını tercih edebiliriz. Ancak bazı durumlarda yaratabileceği farklardan dolayı “” şeklinde yapılması tavsiye edilir.
Stringleri print etmek için de farklı yöntemler kullanabiliriz. Print objeyi önümüze koyarken cat ise içinde yazan neyse onu verecektir.
## [1] "string"
## string
## [1] "string"
Paste ve cat özellikle birden çok stringi birbirine bağlamak istediğimiz zaman avantajlı olur.
## [1] "Bu hafta R dersinde string konusunu öğrendik"
## Bu hafta R dersinde string konusunu öğrendik
Paste aynı zamanda sıralı print etme istediğimiz durumlarda da yardımcı olur.
## [1] "Merhaba Ece" "Merhaba Onur" "Merhaba Zeynep"
Stringleri arada boşluk olmadan birleştirmek istiyorsak da paste0 kullanabiliriz. Ancak string kendi içinde boşluğa sahipse bu boşluk doğal olarak kalıyor.
## [1] "Bugün R dersindestringkonusunu öğrendik"
Eğer istersek belli bir ayraç kullanıp parçaları onunla da ayırabiliriz.
## [1] "Merhaba,Ece" "Merhaba,Onur" "Merhaba,Zeynep"
Stringlerin belli bir kısmını da almamız mümkündür.
## [1] "Bu h"
İlk örnekte 1 ve 4.endeksler arasını aldık. Dikkat etmemiz gereken bir nokta da boşlukların da endekslerden sayıldığı.
## [1] "hafta string öğreniyoruz"
Burdada 4.endeskten sona kadar alıyoruz.
nchar() ile string içinde boşluklar ve noktalama da dahil kaç karakter olduğunu görebiliriz.
## [1] 3 4 6
Stringleri büyük harf ve küçük harf arasında değiştirebiliriz. titlecase her kelimenin ilk harfini büyük yapar.
upper_case <- toupper(ayırma2)
lower_case <- tolower("PATATES")
title_case <- tools::toTitleCase(ayırma2)
upper_case
## [1] "HAFTA STRING ÖĞRENIYORUZ"
## [1] "patates"
## [1] "Hafta String Öğreniyoruz"
Bu tarz işlemler basit, kısa ve hangi harfin nerede oluğunu bildiğimiz durumlarda işe yarar. Ancak gerçek hayatta elimize geçen veriler bu kadar basit olmaz. Üstünde işlem yapmak istediğimiz harfler farklı endekslerde olabilir, öncesinde ve sonrasında başka kelimeler geliyor olabilir. Bu gibi durumlarda her stringe teker teker girmek yerine ortak bir pattern bulup işlem yapmak daha rahat olacaktır. Bunun için R’ın kendi özelliklerini kullanabiliriz.
ulkeler <- c("ABD", "Almanya", "Fransa", "Ingiltere",
"Rusya", "Fransa", "Italya")
grep("fransa", ulkeler)
## integer(0)
## [1] 3 6
## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE
Ilk aramalarımızda büyük harf ve küçük harf farketmişti. Her veri böyle depolanmayacağı için bunun önüne geçebiliriz.
## [1] 3 6
Belirttiğimiz harfin text içinde geçip geçmeiğini de görebiliriz. Bunların hem pozisyonlarını hem de içerdiği elementleri getirebiliriz.
## [1] 2 3 5 6 7
## [1] "Almanya" "Fransa" "Rusya" "Fransa" "Italya"
Burada FALSE belirtemimizin sebebi regex diye adlandırdığımız bir sistemden dolayı. Orada özellikle . ve * gibi işaretler stringden ziyade başka anlamlar da ifade ettiği için FALSE diyerek onları string gibi kullanırız. Regexi bu derste göreceğiz zaten.
Patternları bulduğumuz gibi replace de edebiliriz.
Bu komut her string içinde ilk karşılayan elementi değiştirir.
Bu komutla da karşılayan bütün elementleri değiştirmesini söylüyoruz.
Bu konuları pratik bir örneğe dökecek olursak
string_data <- data.frame(
isim = c("Ece Ucar", "Zeynep_Onal",
"Onur.Gitmez", "ece;ucar")
)
string_data$isim <- gsub("[_;.]", " ", string_data$isim)
string_data$isim <- tools::toTitleCase(string_data$isim)
grepl("Ucar", string_data$isim)
## [1] TRUE FALSE FALSE TRUE
Şu ana kadar öprendiğimiz konular da aslında regex altına giriyordu. Regex, elimize gelen veri temiz değilse onu temizlemeye yarar. Bununla çalışırken şu ana kadar base R komutlarını öğrendik ve şimdi temel regex komutlarına bakacağız. Ancak diğer işlemlerde olduğu gibi bunun için de özel yazılan R paketleri var. Buna sonradan değineceğiz. Regex ile metakarakter ve özel karakterler kullanarak aramalarımızı gerçekleştirebiliriz. Önceden kullandığımız örnekte fixed false olarak belirtmemizin sebebi de buydu. Bu karakterler özel bir anlama geldiği için regex farklı davranışlar sergileyebilirdi. Burada bu davranışların ne olduğunu kısaca göreceğiz. Normalde çok geniş bir konu olduğu için çok kısaca bahsedeceğim.
Regex daha önceden gördüğümüz bir örnek aslında ama hemen hatırlamak gerekirse, direkt textin karakterleri üstünden regex işlemi yapabiliriz.
## [1] TRUE
## [1] FALSE
Metacharacter dedğimiz işaretler ise regex için bir anlam ifade eder. Ondan dolayı bunları kullanırken dikkat etmemiz gerekir. Mesela $ işareti o kelimeyi stringin sonunda aramamız gerekiğini söylediği için dog TRUE sonucu verirken lazy false dedi. Bunu belli stringlerin ne ile bittiğini görmek için kullanabiliriz. Daha bunun gibi dolusuna regex karakteri olduğu için hepsinden bahsetmek mümkün değil.
## [1] TRUE
## [1] FALSE
[] arasına almamız ise onun arasına aldığımız karakterleri string içinde aratır.
## [1] TRUE
Bütün string işlemlerini ortak bir kod bazına oturtmak için stringr paketini kullanabiliriz. Böylece hem bazı işlemleri daha hızlıca yapabilir hem de daha anlaşılır olmasını sağlayabiliriz.
Stringin uzunluğunu bulmak için
## [1] 44
Stringleri birleştirmek için
## [1] "Zeynep Önal"
Stringin içinden bir kısmı çıkartmak için
## [1] "e quic"
Boyut değiştirmek için:
## [1] "THE QUICK BROWN FOX JUMPS OVER \nTHE LAZY DOG"
## [1] "the quick brown fox jumps over \nthe lazy dog"
## [1] "The Quick Brown Fox Jumps Over \nThe Lazy Dog"
Pattern üstüne çalışma
## [1] TRUE FALSE TRUE
## [1] "elma" "ananas"
Replace etme. İlki sadece ilk gördüğünü replace ederken, ikinici tamamını replace eder. Ancak burada dikkat edilmesi gereken nokta bunların case sensitive olduğudur.
## [1] "a quick brown fox jumps over \nthe lazy dog"
## [1] "a quick brown fox jumps over \na lazy dog"
Aynı mantığı kelimeleri stirng içinden atmak için de kullanabiliriz.
## [1] "the quick brown jumps over \nthe lazy dog"
## [1] " quick brown fox jumps over \n lazy dog"
Stringleri belli bir ayraca göre bölmemiz de mümkün. Burada boşluğu ayırma aracı olarak kullandım ancak virgül ve nokta gibi şeyleri de kullanabiliriz.
## [[1]]
## [1] "the" "quick" "brown" "fox" "jumps" "over" "\nthe" "lazy" "dog"
Son olaraksa whitespace dediğimiz bir kavram var. Bu stringlerdeki boşluklar anlamına geliyor. Mesela string başında veya sonunda boşluk bırakırsak orada obje olmamasına rağmen bu varmış gibi görünür. Bundan kurtulmamız string ile daha rahatça çalışmamıza yardımcı olur.
## [1] "R Dersi"
Belli bir patterna uyan stringleri cikarmak icin
## [1] "385"
## [[1]]
## [1] "385" "672"
Stringlerin bulundugu cokumnlari bolebiliriz
library(tidyverse)
string_data <- separate(string_data,
isim,
into = c("first_name",
"last_name"),
sep = " ")
ve birlestirebiliriz
Token dedigimiz sey bir texti tekli kelimelere ve alt kelimelere indirgemekle alakalidir.
library(tokenizers)
text <- "R dersinde text process ogreniyorum"
tokens <- tokenize_words(text)
print(tokens)
## [[1]]
## [1] "r" "dersinde" "text" "process" "ogreniyorum"
Stemming dedigimiz islem kelimeleri koklerine indirger, lemmatization ise sozluk hallerine indirger
library(SnowballC)
words <- c("running", "runs", "ran")
stemmed <- wordStem(words, language = "english")
print(stemmed)
## [1] "run" "run" "ran"
Elimize bir text verisi gectigi zaman bunu analiz etmeden once icinde cok kullanilan kelimleri cikarmamiz gerekir. Bu kelimere stopwords deriz. Bu Ingilizce icin direkt paketle gelirken Turkce icin ek paket kullanmak gerekiyor.
library(tm)
text <- "This sentence will be used as
the primary example of a stopwords removing
tool which is important in the area of
text analysisis and NLP"
words <- unlist(strsplit(text, " "))
cleaned <- words[!words %in% stopwords("english")]
print(cleaned)
## [1] "This" "sentence" "will" "used" "\nthe"
## [6] "primary" "example" "stopwords" "removing" "\ntool"
## [11] "important" "area" "\ntext" "analysisis" "NLP"
Gordgumuz uzere cok temel kelimelerin hepsi elenmis oldu.
Iki stringin birbirine ne kadar benzer olduguna da bakabiliriz. Levenshtein Distance kac karakter edti ile bir stringin digerine donusecegini hesaplar.
##
## Attaching package: 'stringdist'
## The following object is masked from 'package:tidyr':
##
## extract
## [1] 3
Cosine Similarity ise daha komplike bir yontemle 0 olmayan vektorlerin acisinin kosinusunu alip hesaplar. Yine de bize benzerlik orani verir.
library(text2vec)
text1 <- "The quick brown fox"
text2 <- "The fast brown fox"
tokens <- word_tokenizer(c(text1, text2))
it <- itoken(tokens)
v <- create_vocabulary(it)
vectorizer <- vocab_vectorizer(v)
dtm <- create_dtm(it, vectorizer)
cosine_similarity <- sim2(dtm,
method = "cosine")
print(cosine_similarity)
## 2 x 2 sparse Matrix of class "dsCMatrix"
## 1 2
## 1 1.00 0.75
## 2 0.75 1.00
Gün ve zaman çokça kullanacağımız bir veri tipi olacak. Özellikle analiz yaparken veya görselleştirme yaparken verilerin sıralanması açısından önemli olacak. Bunu bir veri altında düzgün ve consistent bir formatta tutmak için ise bu konuyu öğrenmek gerekir. Aynı zamanda lag değişken kullandığımız bir durum olursa bunu da date ve time üstüe kurmamız gerekebilir. R’da farklı gün-zaman verisi tipi vardır. Bunlar doğrudan gün olarak kaydettiğimiz ve bilgisayarların tarih başlangıcı olan 1970-01-01 tarihi. Bu iki farklı veri tipini de görebiliriz ancak düz kullanacağımız veri setleri büyük ihtimalle gerçek tarih ve date veri tipi ile oluşturulmuş olacak.
R’da standart olarak YYYY-MM-DD formatını kullanırız. Bu büyükten küçüğe sıraladığı için de tercih edilen bir yöntemdir.
Ancak istersek tarihi oluştururken hangi formatta oluşturmak istediğimizi belirtebiliriz.
Bu tarihlerin içinden farklı bilgileri ve kısımları çekebiliriz.
## [1] "2024"
## [1] "Tuesday"
## [1] "September"
## [1] "Q3"
Date olarak oluşturmanın yanısıra 1900 başlangıçlı olan bir veri tipini de POSIX olarak oluşturabiliriz. Burada iki farklı oluşturma opsiyonu var. birisi düz obje olarak diğeriyse liste olarak oluşturma. Farklı analizler farklı yöntemler gerektirebilir, düz olarak oluşturmak daha az yer kaplarken, liste olarak oluşturmak farklı componentlara erişmek için daha rahat olabilir.
datetime1 <- as.POSIXct("2024-09-03
10:15:30",
format =
"%Y-%m-%d
%H:%M:%S")
datetime2 <- as.POSIXlt("2024-09-03
10:15:30",
format = "%Y-%m-%d
%H:%M:%S")
Oluşturduğumuz bir karakteri de posix verisine ve date tipine çevirebiliriz.
date_1 <- "03-09-2024 10:15:30"
datetime3 <- strptime(date_1,
format = "%d-%m-%Y
%H:%M:%S")
datetime4 <- as.Date(date_1,
format = "%d-%m-%Y
%H:%M:%S")
Bunun tam tersini de yapabiliriz.
Bu veri tipinin içinden bilgi çıkartmak için ise named list mantığında yaklaşabiliriz. Burada 1900 eklememiz veri tipi 1900 yılından donra gelen yıl sayısını saydığı içim, 1 eklememiz ise tamamen programlama ise alakalı. Bu yüzden sosyal bilimlerde çok tercih edeceğimiz bir veri saklama yöntemi değil.
## [1] 2024
## [1] 9
## [1] 3
Gün ve zamanlar üstünde aritmetik işlemler de yapabiliriz.
Fark hesaplama
## Time difference of 7 days
Karşılaştırma
## [1] TRUE
Ikinci bir yontemle fark hesaplama. Bu cok daha detayli bir fark gosterecek.
## [1] "26179200s (~43.29 weeks)"
Daha detayli olarak zaman araligini gormek icin
start_date <- ymd("2023-01-01")
end_date <- ymd("2024-01-01")
time_interval <- interval(start_date,
end_date)
print(time_interval)
## [1] 2023-01-01 UTC--2024-01-01 UTC
Belirtilen tarih o aralikta mi bakmak icin
## [1] TRUE
Timezone dönüştürme
Bu paket ileride daha çok da kullanılacak.
datetime_utc <- as.POSIXct("2024-09-03
10:15:30",
tz = "UTC")
datetime_istanbul <- as.POSIXct("2024-09-03
10:15:30",
tz = "Europe/Istanbul")
datetime_dönüşme <- with_tz(datetime_istanbul,
"America/New_York")
Lubridate paketi R’da tarih ve zaman ile çalışırken en çok kullanacağımız paketlerden birisidir. Tarihler ile çalışmayı kolaylaştırır ve R’ın temel fonksiyonlarından kurtarıp daha mantıklı bir altyapıya oturtur.
## [1] 2024
## [1] 9
## [1] Wed
## Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat
Lubridate ile ekleme ve çıkarma yapması da çok daha kolay oluyor
Tarihlerle ilgili en önemli konulardan birisi de farklı gün veri formatlarını birbirine dönüştürmek. Her zaman elimizde consistent bir veri formatı olmayacak ve bunlar üstünden bir analiz yapmamız gerekirse error alacağız. Twitter verisinde bile karşılaşabileceğimiz bir durum olduğu için nasıl çözeriz önemli bir mesele oluyor.
Burdaki veride hem ayraç farkını hem de gün formatının giriliş farkını görmüş olduk. Bunu çözmemiz doğru bir analiz için önemli olacak. Bunu normalde çok uzun yollarla yapabiliriz ancak lubridate ile daha kolay yapmamız da mümkün.
dates_df$standard_date[is.na(dates_df$
standard_date)] <- as.Date(dates_df$date[is.na(dates_df$
standard_date)],
format = "%m/%d/%Y")
dates_df$standard_date[is.na(dates_df$standard_date)] <-
as.Date(dates_df$date[is.na(dates_df$standard_date)],
format = "%d.%m.%Y")
dates_df$lubridate_date <-
parse_date_time(dates_df$date,
orders = c("ymd", "mdy",
"dmy", "ymd HMS"))
Bu komut ile hem farklı formatları hem de farklı seperatörleri ve yazım formatalarını aynı anda çözebiliyoruz. Ancak bunu paket dışı yöntem ile çözmek isteseydik daha uzun olacaktı. Yukarıdaki örnekte olduğu gibi uzun uzun uğraşmak yerine çok daha rahat bir şekilde bunu çözebiliriz. Böylece tarihin olduğu bir veri ile çalışmamız çok daha kolay olacak.