R Dersleri - Ali Onur Gitmez
Bu son kisimdaysa gecen hafta causal inference’a giris yaptigimiz gibi sosyal bilimlerde sikca kullanilan computational metodlara bir giris yapip orneklerine bakacagiz. Bu yontemler
olacak. Bunlarin hepsi ozellikle son donemlerde yaygin bir sekilde sosyal bilimler alaninda kullaniliyor ve calisilan konuya gore de onemleri yuksek. Bundan dolayı uygulamalı olarak temel bir giriş yapmak önemli olacaktır.
DiÄŸer paketler
library(tidyverse)
library(hms)
library(stringr)
library(writexl)
library(readxl)
library(lubridate)Scraping paketleri
Text paketleri
Bir siteden veri cekmek icin once robots.txt kismina bakariz. Orada hangi sayfaların çekmeye uygun olup olmadığını görebiliriz. Bir örnek bile bunu deneyelim.
Sabah Gazetesi’nin sayfasından verileri çekeceğimizi varsayalım. Bunun için öncelikle robots.txt kısmına bakarız. Bunun sonrasında verileri çekebileceğimiz sayfayı bulmamız lazım. Bunun için ya sayfa içinde arama yapmak bir çözüm olabilir. Verileri çekmek için farklı yöntemler kullanabiliriz. Bunlardan ilki HTML ile çekmek olacak. Neredeyse websitesi HTML formatı üstünde bir yapıya kurulu olur ve bunu kullanarak site içinden resim, yazı veya tablo çekebilirsiniz.
h1 ve p gibi kısımlara node deriz. Bunlar veriyi çekmemiz için en önemli kısımlar çünkü bütün veriler bunların altında saklanıyor. Sayfa yapısını inspect ederek veya belli uzantılar aracılığıyla bakarak neyin hangi yapıda olduğunu anlayabiiriz. Şimdi bir örnek ile görelim.
url <- "http://books.toscrape.com/index.html"
webpage <- read_html(url)
titles <- webpage %>%
html_nodes("h3 a") %>%
html_attr("title")
titles## [1] "A Light in the Attic"
## [2] "Tipping the Velvet"
## [3] "Soumission"
## [4] "Sharp Objects"
## [5] "Sapiens: A Brief History of Humankind"
## [6] "The Requiem Red"
## [7] "The Dirty Little Secrets of Getting Your Dream Job"
## [8] "The Coming Woman: A Novel Based on the Life of the Infamous Feminist, Victoria Woodhull"
## [9] "The Boys in the Boat: Nine Americans and Their Epic Quest for Gold at the 1936 Berlin Olympics"
## [10] "The Black Maria"
## [11] "Starving Hearts (Triangular Trade Trilogy, #1)"
## [12] "Shakespeare's Sonnets"
## [13] "Set Me Free"
## [14] "Scott Pilgrim's Precious Little Life (Scott Pilgrim #1)"
## [15] "Rip it Up and Start Again"
## [16] "Our Band Could Be Your Life: Scenes from the American Indie Underground, 1981-1991"
## [17] "Olio"
## [18] "Mesaerion: The Best Science Fiction Stories 1800-1849"
## [19] "Libertarianism for Beginners"
## [20] "It's Only the Himalayas"
prices <- webpage %>%
html_nodes(".price_color") %>%
html_text() %>%
sub("£", "", .) %>%
as.numeric()
prices## [1] 51.77 53.74 50.10 47.82 54.23 22.65 33.34 17.93 22.60 52.15 13.99 20.66
## [13] 17.46 52.29 35.02 57.25 23.88 37.59 51.33 45.17
ratings <- webpage %>%
html_nodes(".star-rating") %>%
html_attr("class") %>%
sub("star-rating ", "", .)
ratings## [1] "Three" "One" "One" "Four" "Five" "One" "Four" "Three" "Four"
## [10] "One" "Two" "Four" "Five" "Five" "Five" "Three" "One" "One"
## [19] "Two" "Two"
books_df <- data.frame(
Title = titles,
Price = prices,
Rating = ratings,
stringsAsFactors = FALSE
)Benzer şekilde websitelerindeki tabloları da çekebiliriz. Burada tabloyu sitede gördüğümüz şekliyle çektiğini görüyoruz.
url2 <- "https://en.wikipedia.org/wiki/List_of_largest_companies_in_the_United_States_by_revenue"
webpage2 <- read_html(url2)
tables <- webpage2 %>% html_nodes("table.wikitable")
companies_table <- tables[[1]] %>% html_table()Xpath ile de veri çekebiliriz. xpath, html ve xml dökümanları ile çalışmak için güçlü bir tool. Bunu HTML lokasyonlarını öğrenmek için de her objenin kendi yerini öğrenmek için de kullanabiliriz.
url4 <- "http://quotes.toscrape.com/"
webpage4 <- read_html(url4)
quotes <- webpage4 %>%
html_nodes(xpath = '/html/body/div[1]/div[2]/div[1]/div[1]/span[1]') %>%
html_text() %>%
gsub("^\\s+|\\s+$", "", .)Bu şekilde manüel seçimler yapmak yeriine toplu bir şekilde de veri çekebiliriz. Sabah Gazetesi öğreneğine dönecek olursak:
sitemap_urls <- c("https://www.sabah.com.tr/sitemaparchives/post/2023-1.xml",
"https://www.sabah.com.tr/sitemaparchives/post/2023-2.xml",
"https://www.sabah.com.tr/sitemaparchives/post/2023-3.xml",
"https://www.sabah.com.tr/sitemaparchives/post/2022-12.xml")2023 yılının ilk 3 ayında Sabah gazetesinde yayınlanmış haberleri çekelim.
df_sabah <- map_dfr(sitemap_urls, function(url) {
sabah_data <- read_xml(url)
sabah_urls <- xml_text(xml_find_all(sabah_data, "//d1:loc"))
sabah_dates <- xml_text(xml_find_all(sabah_data, "//d1:lastmod"))
sabah_links <- tibble(urls = sabah_urls, dates = sabah_dates)
sabah_links_2 <- sabah_links %>%
filter(str_detect(dates, "^2023-(01|02|03)")) %>%
mutate(dates = substr(dates, 1, 10))
return(sabah_links_2)
})
num_stories <- nrow(df_sabah)
sprintf("In the first 3 months of 2023, Sabah published %d stories.", num_stories)## [1] "In the first 3 months of 2023, Sabah published 47228 stories."
Sonra bu haberlerin kategorizasyonunu yapalım
df_sabah <- df_sabah %>%
mutate(category = str_extract(urls, "(?<=sabah.com.tr\\/)[^\\/]+")) %>%
mutate(category = case_when(
category %in% c("dunya") ~ "World",
category %in% c("egitim") ~ "Education",
category %in% c("ekonomi", "finans") ~ "Economy",
category %in% c("gundem") ~ "Politics",
category %in% c("kultur-sanat", "magazin", "medya") ~ "Entertainment",
category %in% c("spor") ~ "Sports",
category %in% c("yazarlar") ~ "Opinion",
TRUE ~ "Others"
))df_sabah %>%
count(category) %>%
mutate(category = reorder(category, -n)) %>%
ggplot(aes(x = category, y = n, fill = category)) +
geom_bar(stat = "identity") +
ggtitle("Number of News by Category in Sabah Newspaper 2023-01/03") +
xlab("Category") +
ylab("Count") +
theme_bw() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
theme(legend.position = "none")Haber başlıklarında kaç kere Kılıçdaroğlu kaç kere Erdoğan geçmiş diye bakalım
count_df <- df_sabah %>%
mutate(names = str_extract_all(urls, "erdogan|kilicdaroglu")) %>%
unnest(names) %>%
count(names)
sabah_stories <- df_sabah %>%
filter(str_detect(urls, "kilicdaroglu|erdogan")) %>%
distinct(urls, .keep_all = TRUE)
invisible(any(duplicated(sabah_stories$urls)))
paste0("Erdogan appears ", count_df$n[1],
" times, and Kilicdaroglu appears ", count_df$n[2], " times.")## [1] "Erdogan appears 1020 times, and Kilicdaroglu appears 314 times."
Haber içerikleri analizini yapalım
sabah_stories <- sabah_stories %>%
filter(category == "Politics")
sabah_stories_combined <- data.frame(title = rep(NA, nrow(sabah_stories)),
publish_date = rep(NA, nrow(sabah_stories)),
main_text = rep(NA, nrow(sabah_stories)),
erdogan = rep(NA, nrow(sabah_stories)),
url = rep(NA, nrow(sabah_stories)),
stringsAsFactors = FALSE)
sabah_stories_combined <- sabah_stories_combined %>%
mutate(publish_date = sabah_stories$dates) %>%
mutate(urls = sabah_stories$urls) %>%
mutate(erdogan = ifelse(grepl('erdogan', urls), 1, 0)) %>%
select(title, publish_date, main_text, erdogan, urls)Hem haber başlığını hem de textini çıkaralım
for (i in seq_along(sabah_stories$urls)) {
# get HTML content
html <- read_html(sabah_stories$urls[i])
# Extract title
title <- html %>% html_nodes("h1.pageTitle") %>% html_text()
# Extract main text
main_text_p <- html %>%
html_nodes("p") %>%
html_text()
if (length(main_text_p) > 0) {
main_text <- main_text_p
} else {
main_text_newsBox <- html %>%
html_nodes(".newsBox.selectionShareable") %>%
html_text()
main_text <- main_text_newsBox
}
sabah_stories_combined$title[i] <- title
sabah_stories_combined$main_text[i] <- paste(main_text, collapse = "\n")
Sys.sleep(7)
}Kaydedelim ve tekrar çağıralım
sabah_stories_combined <- read_csv("sabahstories.csv")
sabah_stories_combined$publish_date <- as.Date(sabah_stories_combined$publish_date)Günlük olarak çıkan haberlere bakalım
counts <- sabah_stories_combined %>%
mutate(date = as.Date(publish_date, format = "%Y-%m-%d")) %>%
group_by(date) %>%
summarise(erdogan_count = sum(grepl("erdogan", urls, ignore.case = TRUE)),
kilicdaroglu_count = sum(grepl("kilicdaroglu", urls, ignore.case = TRUE))) %>%
ungroup()Başlıklardan noktalamaları çıkaralım, küçük harfe çevirelim ve içinde kılıcdaroğlu geçenleri ayrı bir değişkene alalım.
sabah_stories_combined$title2 <-
str_to_lower(str_replace_all(sabah_stories_combined$title,
"[[:punct:]]", ""))
sabah_stories_combined <- sabah_stories_combined %>%
mutate(kilicdaroglu = ifelse(grepl('kilicdaroglu', urls), 1, 0))Stopwords ekleyelim. Bunu R’ın içinde Türkçe stopwords olmadığı için ayrı paketle yapıyoruz.
Erdoğan geçen başlıklardaki kelimeleri sayalım
erdogan_words <- sabah_stories_combined %>%
filter(erdogan == 1) %>%
select(title2) %>%
unnest_tokens(word, title2) %>%
filter(!word %in% c("son", "dakika",
tr_stopwords, "recep", "tayyip", "daki̇ka")
& !grepl("erdoÄŸan", word)) %>%
count(word, sort = TRUE)Aynısını Kılıçdaroğlu için yapalım
kilicdaroglu_words <- sabah_stories_combined %>%
filter(kilicdaroglu == 1) %>%
select(title2) %>%
unnest_tokens(word, title2) %>%
filter(!word %in% c("son", "dakika",
tr_stopwords, "kemal", "daki̇ka") &
!grepl("kılıçdaroğlu", word)) %>%
count(word, sort = TRUE)İkisi için de en çok kullanılan 15 kelimeyi çıkaralım.
top_erdogan_words <- erdogan_words %>%
slice_head(n = 15)
top_kilicdaroglu_words <- kilicdaroglu_words %>%
slice_head(n = 15)erdogan_plot <- ggplot(top_erdogan_words,
aes(x = reorder(word, n), y = n)) +
geom_bar(stat = "identity", fill = "orange") +
labs(title = "Most Common Words in Erdogan Titles",
y = "Word", x = "Count") +
theme_minimal() +
theme(axis.text.y = element_text(angle = 0, hjust = 1)) +
coord_flip()
ggsave("erdogan.png", dpi = 300)kilicdaroglu_plot <- ggplot(top_kilicdaroglu_words,
aes(x = reorder(word, n), y = n)) +
geom_bar(stat = "identity", fill = "red") +
labs(title = "Most Common Words in Kilicdaroglu Titles",
y = "Word", x = "Count") +
theme_minimal() +
theme(axis.text.y = element_text(angle = 0, hjust = 1)) +
coord_flip()
ggsave("kilicdaroglu.png", dpi = 300)Bunu world cloud olarak da yapabiliriz.
kilicdaroglu_wordcloud <- ggplot(top_kilicdaroglu_words,
aes(label = word, size = n)) +
geom_text_wordcloud() +
scale_size_area(max_size = 15) +
theme_void() +
labs(title = "Most Common Words in Kilicdaroglu Titles")
kilicdaroglu_wordclouderdogan_wordcloud <- ggplot(top_erdogan_words,
aes(label = word, size = n)) +
geom_text_wordcloud() +
scale_size_area(max_size = 30) +
theme_void() +
labs(title = "Most Common Words in Erdogan Titles")
erdogan_wordcloudText analizi kısmında textin kendisine ve içinde kelime olarak geçtiğine odaklanmıştık ancak içerik olarak nelerden bahsettiklerine hiç bakmadık.
## New names:
## • `` -> `...1`
Önce verimizi alıp analiz için hazırlayalım
dfm <- dfm(corpus(sentiment$fulltext) %>%
tokens(remove_punct = TRUE) %>%
tokens_tolower() %>%
tokens_remove(tr_stopwords) %>%
tokens_wordstem(language = "tr")) Haberleri konulara bölelim ve beraber bulundukları haberlere göre ortlama olarak nasıl ayrıldıklarına bakalım.
set.seed(94)
lda_model <- textmodel_lda(dfm, k = 10)
top_terms <- terms(lda_model, n= 10)
top_terms_df <- data.frame(top_terms)
top_terms_df_1 <- top_terms_df[ , 1:5]
top_terms_df_2 <- top_terms_df[ , 6:10]
gt_table_1 <- gt::gt(top_terms_df_1) %>%
gt::tab_header(title = "Top Terms per Topic (1-5)")
gt_table_2 <- gt::gt(top_terms_df_2) %>%
gt::tab_header(title = "Top Terms per Topic (6-10)")| Top Terms per Topic (1-5) | ||||
| topic1 | topic2 | topic3 | topic4 | topic5 |
|---|---|---|---|---|
| kılıçdaroğlu | erdoğa | em | kemal | erdoğa |
| genel | millet | erdoğa | bay | yıl |
| parti | seç | çocuk | millet | ülke |
| kemal | genç | dedi | işçi | millet |
| başka | başka | ev | iş | büyük |
| chp | ak | hesap | baÅŸka | son |
| kılıçdaroğlu'n | ülke | medya | ifade | başka |
| aday | söz | atık | erdoğa | ala |
| hdp | an | eÅŸ | ada | yer |
| i̇yi̇ | parti | erdoğan' | diyecek | dünya |
| Top Terms per Topic (6-10) | ||||
| topic6 | topic7 | topic8 | topic9 | topic10 |
|---|---|---|---|---|
| başka | ülke | depre | başka | su |
| erdoğa | türki | erdoğa | cumhurbaşkan | açılış |
| recep | türk | vatandaş | terör | lira |
| tayyip | dünya | başka | medya | yol |
| cumhurbaşka | uluslararas | çalışma | erdoğan' | başka |
| genel | konu | bölge | i̇sveç' | yüz |
| ziyaret | el | konut | karar | proje |
| erdoğan' | barış | felaket | örgüt | tünel |
| görüşme | halk | afet | eyle | i̇stanbul |
| kabul | ilişki | yer | i̇sveç | yatır |
Bu sefer 5 konu altınada toplarlayıp farkına bakalım. Ne değişti?
set.seed(94)
lda_model2 <- textmodel_lda(dfm, k = 5)
top_terms2 <- terms(lda_model2, n = 10)
top_terms2_df <- data.frame(top_terms2)
gt_table_3 <- gt::gt(top_terms2_df) %>%
gt::tab_header(title = "Top Terms per Topic")
gt_table_3| Top Terms per Topic | ||||
| topic1 | topic2 | topic3 | topic4 | topic5 |
|---|---|---|---|---|
| baÅŸka | erdoÄŸa | erdoÄŸa | baÅŸka | millet |
| parti | depre | yıl | erdoğa | erdoğa |
| genel | başka | başka | cumhurbaşka | ülke |
| kılıçdaroğlu | vatandaş | ülke | tayyip | genç |
| kemal | bölge | dünya | recep | söz |
| chp | çalışma | su | türk | siz |
| aday | konut | açılış | erdoğan' | an |
| kılıçdaroğlu'n | felaket | erdoğan' | görüşme | zama |
| cumhurbaşka | devlet | proje | türki | türki |
| 6 | afet | tarih | kabul | dedi |
topics <- topics(lda_model2)
sentiment$Topic <- topics
topic_labels <- c("Erdogan","Turkey", "Kilicdaroglu", "Earthquake", "Election" )
sentiment$Topic <- factor(sentiment$Topic, labels = topic_labels)
topic_counts <- table(sentiment$Topic)
topic_counts <- as.data.frame(topic_counts)| Top Terms per Topic | ||||
| topic1 | topic2 | topic3 | topic4 | topic5 |
|---|---|---|---|---|
| an | hdp | konut | emine | hizmet |
| terör | masa | felaket | türk | i̇stanbul |
| i̇sveç | akşener | depremzede | görüşme | dünya |
| 14 | i̇yi̇ | kahramanmaraş | dünya | alan |
| bay | adaylık | ev | kabul | proje |
| genç | lı | afet | halk | su |
| mayıs | partisi | hatay | uluslararası | kadın |
| siyasi | koalisyon | il | mesaj | sahip |
| masa | isim | yardım | ilet | hayat |
| örgüt | görüşme | bura | atık | yatırım |
Konu başına haç haber düştüğünü bu şekilde de görebiliriz
| Cluster | Frequency |
|---|---|
| 1 | 7 |
| 2 | 35 |
| 3 | 6 |
| 4 | 64 |
| 5 | 480 |
Kelimeleri pozitif ne negatif olarak bölelim. Bunu şimdi öğrenmeyeceğimiz lasso regresyonu diye bir yöntemle yapıyoruz ve böylece hangi kelimelerin neyi tahmin ettiğini görebiliyoruz. Bu kelimeler negatif veya pozitif olarak grupladığımız haberlerde en çok geçen kelimeler.
predictors <- convert(dfm, to = 'matrix')
response <- sentiment$erdogan
set.seed(94)
lasso <- cv.glmnet(predictors, response, family = "binomial", alpha = 1)
tmp_coeffs <- coef(lasso, s = "lambda.min")
coeffs_df <- data.frame(name = tmp_coeffs@Dimnames[[1]][tmp_coeffs@i + 1], coefficient = tmp_coeffs@x)
coeffs_df <- coeffs_df[coeffs_df$name != "(Intercept)",]
coeffs_df <- coeffs_df[order(-abs(coeffs_df$coefficient)),]
top_positive_words <- head(coeffs_df[coeffs_df$coefficient > 0,], 10)
top_negative_words <- head(coeffs_df[coeffs_df$coefficient < 0,], 10)Negatif haberlerde en çok geçen kelimeler
| Top Positive Words | |
| Word | Coefficient |
|---|---|
| ereÄŸli' | 7.2696803 |
| beledi̇yeni̇n | 2.5043161 |
| baÅŸvura | 2.4157332 |
| tazmina | 2.3183030 |
| toplanmış | 1.7814972 |
| daires | 1.0560055 |
| yama | 0.9433218 |
| tayyip | 0.6628557 |
| etkileÅŸim | 0.6190165 |
| onardi | 0.4788912 |
Pozitif haberlerde en çok geçen kelimeler
top_negative_words <- gt::gt(top_negative_words) %>%
gt::tab_header(title = "Top Negative Words") %>%
gt::cols_label(name = "Word", coefficient = "Coefficient")
top_negative_words| Top Negative Words | |
| Word | Coefficient |
|---|---|
| kılıçdaroğlu’n | -4.749593 |
| sevigen' | -4.154531 |
| ağırlayarak | -3.702199 |
| flört | -3.103029 |
| pervasız | -2.786683 |
| kılıçdaroğlu’na | -2.731575 |
| tüm | -2.563847 |
| mensubiyet | -2.469966 |
| çürüdü | -2.436991 |
| açiklama | -2.348500 |
İsimleri çıkarıp bir daha bakalım
coeffs_df <- coeffs_df[-grep('erdoğa|kılıçdaroğlu|tayyip|recep|kemal', coeffs_df$name), ]
coeffs_df <- coeffs_df[order(-abs(coeffs_df$coefficient)),]
top_words <- head(coeffs_df, 10)Bunu yaparken dikkat edilmesi gereken noktayı hatırlatmak gerekirse: robots.txt dışına çıkmak etik olarak görülmez ve zaten bir çok sitede buna yönelik engeller vardır. Sürekli veri çekmeye çalışırsanız da sizi IP üstünden geçici veya kalıcı olarak engelleyebilir. Bu da ileride herhangi bir çalışma yapmamızın önüne geçer.
Bazı sitelerse doğrudan scrape edilmeyi istemezler ancak application programming interface (API) aracılığıyla buna izin verirler. Bunlar ücretli veya ücretsiz olabilir ancak düzenli bir veri çekimine olanak tanırlar.
Daha advanced sentiment analiz icin R’in paketleri var ancak bunlar Ingilizce ile calisiyor. Turkce yapmak icinse Python kullanmamiz lazim. Neyse ki R kullanirken Python cagirip isimizi yapitrabiliyoruz.
Once Python islemlerini yapalim
from transformers import AutoModelForSequenceClassification, AutoTokenizer, pipeline
import pandas as pd
import warnings
from openpyxl import Workbook
warnings.filterwarnings('ignore', category=FutureWarning)
warnings.filterwarnings('ignore', category=UserWarning)
model = AutoModelForSequenceClassification.from_pretrained("savasy/bert-base-turkish-sentiment-cased")
tokenizer = AutoTokenizer.from_pretrained("savasy/bert-base-turkish-sentiment-cased")
sa = pipeline("sentiment-analysis", tokenizer=tokenizer, model=model, device=-1)
input_file = "/Users/alionurgitmez/Desktop/R Dersi/Hafta 15/sabah_PS2.xlsx"
output_file = "after_analysis.xlsx"
df = pd.read_excel(input_file)
print(df.head())## Unnamed: 0 ... lemmatized_fulltext
## 0 0 ... Başkan Erdoğan dan Ali İhsan Destici taziye me...
## 1 1 ... Emine Erdoğan vatandaş böyle seslen Duyarlı he...
## 2 2 ... Başkan Erdoğan Yeni Azerbaycan Partisi Gençler...
## 3 3 ... Son dakika Denizli emekçi kadın buluş Başkan E...
## 4 4 ... O fotoÄŸraf kahraman konuÅŸ Huriye teyze ErdoÄŸan...
##
## [5 rows x 8 columns]
Burada sentiment paketini calistiyoruz
sentiment_results = df['title'].apply(lambda x: sa(x)[0])
df['sentiment_label'] = [result['label'] for result in sentiment_results]
df['sentiment_score'] = [result['score'] for result in sentiment_results]
df.to_excel(output_file, index=False)Burada kaydettigimiz veriyi R’a aliyoruz. Boylece R’a geri donmus olduk. Ikisi de ayni anda calisabiliyor.
## [1] "Average positive sentiment score of Kilicdaroglu articles is: 0.85"
## [1] "Average positive sentiment score of Erdogan articles is: 0.91"
Gorsellestirmesini de yapalim
sabah_stories_positive$date <- as.Date(sabah_stories_positive$date)
average_sentiment2 <- sabah_stories_positive %>%
mutate(week = as.integer(format(date, "%U"))) %>%
group_by(erdogan, week) %>%
summarize(average_sentiment = mean(sentiment_score))
ggplot(average_sentiment2, aes(x = week, y = average_sentiment, color = factor(erdogan))) +
geom_line() +
labs(x = "Week", y = "Average Sentiment", color = "Leader") +
scale_color_manual(values = c("red", "orange"), labels = c("Kilicdaroglu", "Erdogan")) +
scale_x_continuous(breaks = unique(average_sentiment2$week)) +
theme_minimal()Coğrafi analiz özellikle IR alanında ve conflict çalışmalarında gelişmekte olan bir analiz yöntemi. Siyasi ve fiziksel harita veya uydu bilgilerini kullanarak çıkarımlar yapmamıza olanak sağlıyor. Text analizi gibi çok geniş bir alan olduğu için kısa bir giriş yapacağım. Öncelikle bu alanda zorunlu olan paketleri yükleyelim.
Örnek bir veriyi hazırlayıp bakalım. Bu veri North Carolina sudden infant death syndrome (SIDS) oranlarına bakıyor. Aynı zamanda bu veriyi görselleştirelim. st olarak belirttiğimiz için buna göre görselleştirme yaptı.
## Reading layer `sids' from data source
## `/Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library/spData/shapes/sids.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 100 features and 22 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
## CRS: NA
Her bölge çevresine 10 km bir güvenli alan oluşturalım.
Kesişen alanları bulalım. Bu ilk verimiz ve 10 km koyduğumuz veri arasında kesişen alanları gösteriyor.
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
## Warning: plotting the first 10 out of 44 attributes; use max.plot = 44 to plot
## all
Farklı bir görselleştirme alternatifi olarak da bunu kullanabiliriz.
library(tmap)
tm_shape(nc) +
tm_polygons(col = "SID74", palette = "Blues", title = "SIDS Rate 1974") +
tm_layout(legend.outside = TRUE)Haritalar ile çalışmanın farklı bir örneğini de Türkiye seçimleri üstünden görebiliriz. Bunu ilçe bazlı ve il bazlı seçim sonuçları üstünden yapabiliriz.
library(haven)
library(tidyverse)
library(TRmaps)
ilce_election <- read_dta("Elections_wide.dta")
ilce_election <- ilce_election %>% dplyr::select(adm1_tr, adm2_tr, akp_2018P, chp_2018P, mhp_2018P,
iyi_2018P, hdp_2018P, sp_2018P)
ilce_election$adm2_tr <- gsub(".*MERKEZ*", "MERKEZ", ilce_election$adm2_tr)
convert_to_lower <- function(str) {
converted_str <- str_to_sentence(str, locale = "tr")
return(converted_str)
}
ilce_election$adm1_tr <- convert_to_lower(ilce_election$adm1_tr)
ilce_election$adm2_tr <- convert_to_lower(ilce_election$adm2_tr)
ilce_election$il_ilce <- paste(ilce_election$adm1_tr, ilce_election$adm2_tr, sep = "-")
ilce_election <- ilce_election %>% dplyr::select(-adm1_tr, -adm2_tr)
tr_ilce <- as.data.frame(st_as_sf(tr_ilce))
tr_ilce <- tr_ilce %>% dplyr::select(il_ilce, geometry, tuik_no, Shape_Area, Shape_Leng)
tr_ilce <- tr_ilce[tr_ilce$il_ilce != "Hakkari-Derecik", ]
ilce_election <- ilce_election %>%
mutate(il_ilce = ifelse(il_ilce == "Ankara-Kazan", "Ankara-Kahramankazan", il_ilce))
ilce_election <- ilce_election %>%
mutate(il_ilce = ifelse(il_ilce == "Samsun-19 mayıs", "Samsun-19 Mayıs", il_ilce))
ilce_election <- ilce_election %>%
mutate(il_ilce = ifelse(il_ilce == "Kırıkkale-Bahşili", "Kırıkkale-Bahşılı", il_ilce))
final_ilce_election <- merge(ilce_election, tr_ilce, by.x = "il_ilce", by.y = "il_ilce")final_ilce_election$cumhur <- final_ilce_election$akp_2018P + final_ilce_election$mhp_2018P
final_ilce_election$millet <- final_ilce_election$chp_2018P + final_ilce_election$iyi_2018P + final_ilce_election$sp_2018P
final_ilce_election$hdp <- final_ilce_election$hdp_2018P
final_ilce_election$kazanan <- ifelse(final_ilce_election$hdp > final_ilce_election$millet & final_ilce_election$hdp > final_ilce_election$cumhur, "HDP",
ifelse(final_ilce_election$millet > final_ilce_election$hdp & final_ilce_election$millet > final_ilce_election$cumhur, "MILLET",
ifelse(final_ilce_election$cumhur > final_ilce_election$hdp & final_ilce_election$cumhur > final_ilce_election$millet, "CUMHUR", "ESIT")))final_ilce_election_sf <- st_as_sf(final_ilce_election)
my_colors <- c("HDP" = "#8f1ca5", "MILLET" = "red", "CUMHUR" = "orange", "CHP" = "firebrick1",
"MHP" = "darkred", "IYI" = "cyan", "SAADET" = "maroon", "ESIT" = "darkgrey")
ggplot(final_ilce_election_sf) +
geom_sf(aes(fill = kazanan)) +
scale_fill_manual(values = my_colors) +
labs(fill = "Kazanan") +
theme_void() +
ggtitle("Tum Ittifaklar Beraber") Spatial data ile bir analiz öğreneğini inceleyelim. Öncelikle kullanılacak verileri alıp dönüşüm yapıyoruz.
url <- "https://www2.census.gov/geo/tiger/TIGER2019/COUNTY/tl_2019_us_county.zip"
download.file(url, destfile = "us_counties.zip")
unzip("us_counties.zip")## Reading layer `tl_2019_us_county' from data source
## `/Users/alionurgitmez/Desktop/R Dersi/Hafta 15/tl_2019_us_county.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 3233 features and 17 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -179.2311 ymin: -14.60181 xmax: 179.8597 ymax: 71.43979
## Geodetic CRS: NAD83
covid_url <- "https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv"
covid_data <- read.csv(covid_url)
write_csv(covid_data, "covid_data.csv")## Rows: 2502832 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): county, state
## dbl (3): fips, cases, deaths
## date (1): date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
covid_latest <- covid_data %>%
group_by(fips) %>%
filter(date == max(date)) %>%
ungroup() %>%
dplyr::select(fips, cases, deaths)
covid_latest$fips <- as.character(covid_latest$fips)counties_covid <- counties_transformed %>%
left_join(covid_latest, by = c("GEOID" = "fips"))
counties_covid <- counties_covid %>%
mutate(cases_per_100k = (cases / as.numeric(ALAND)) * 100000)Vakaların çok yüksek olduğu yerlere bakalım
hotspots <- counties_covid %>%
arrange(desc(cases_per_100k)) %>%
slice_head(n = 10)
print(hotspots[, c("NAME", "STATEFP", "cases", "cases_per_100k")])## Simple feature collection with 10 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 1930000 ymin: -428834.5 xmax: 2352825 ymax: 140953.9
## Projected CRS: NAD27 / US National Atlas Equal Area
## NAME STATEFP cases cases_per_100k
## 1 Suffolk 25 226017 149.81600
## 2 Hudson 34 179135 149.72731
## 3 Philadelphia 42 317808 91.38143
## 4 District of Columbia 11 143943 90.90732
## 5 Alexandria 51 32647 84.40414
## 6 Arlington 51 46198 68.61124
## 7 Essex 34 222558 68.15279
## 8 Manassas Park 51 3828 58.54358
## 9 Nassau 36 425386 57.70325
## 10 Union 34 151057 56.75346
## geometry
## 1 MULTIPOLYGON (((2322932 130...
## 2 MULTIPOLYGON (((2144411 -12...
## 3 MULTIPOLYGON (((2074643 -24...
## 4 MULTIPOLYGON (((1955476 -40...
## 5 MULTIPOLYGON (((1956985 -41...
## 6 MULTIPOLYGON (((1952303 -40...
## 7 MULTIPOLYGON (((2122970 -12...
## 8 MULTIPOLYGON (((1930000 -42...
## 9 MULTIPOLYGON (((2171046 -10...
## 10 MULTIPOLYGON (((2119662 -14...
Yakındaki yerler üstünden vakaların yüksek olduğu yerleri belirleyelim
high_case_counties <- counties_covid %>%
filter(cases_per_100k > quantile(cases_per_100k, 0.9, na.rm = TRUE))
neighbors <- st_join(counties_covid, high_case_counties, join = st_touches, left = FALSE)
clusters <- neighbors %>%
group_by(GEOID.x) %>%
summarise(cluster_size = n())Şimdiyse elimizdeki verileri görselleştirelim:
library(viridis)
library(scales)
ggplot(data = counties_covid) +
geom_sf(aes(fill = cases_per_100k), color = NA) +
scale_fill_viridis(trans = "log", labels = comma,
name = "Cases per 100,000\n(log scale)") +
theme_minimal() +
theme(legend.position = "right") +
labs(title = "COVID-19 Cases per 100,000 Population by US County",
subtitle = "Data as of latest available date",
caption = "Source: New York Times COVID-19 Data")