# File-Name:       twitter_net.R
# Date:            2012-02-10
# Author:          Drew Conway (drew.cownway@nyu.edu)
# Purpose:         Drugi plik kodu do rozdziału 11.  W tym krótkim pliku generujemy
#                   sieć ego dla danego użytkonwika serwisu Twitter. Po zbudowaniu obiektu
#                   sieci dodajemy do niej pewne atrybuty i oczyszczamy wykresy poprzez
#                   wyodrębnienie 2-core. Na koniec przeprowadzamy analizę grupowania
#                   hierarchicznego, w postaci wykrywania społeczności lokalnych przez badanie odległości
# Data Used:       n/a
# Packages Used:   igraph, see 01_google_sg.R

# All source code is copyright (c) 2012, under the Simplified BSD License.  
# For more information on FreeBSD see: http://www.opensource.org/licenses/bsd-license.php

# All images and materials produced by this code are licensed under the Creative Commons 
# Attribution-Share Alike 3.0 United States License: http://creativecommons.org/licenses/by-sa/3.0/us/

# All rights reserved.

######################################################
####                                              ####
####         OSTRZEŻENIE DLA CZYTELNIKÓW          ####
####                                              ####
#### W kwietniu 2012 roku usługa Google Social    ####
#### Graph została zarzucona, więc poniższy kod   ####
#### nie może być poprawnie wykonany; został      ####
#### zachowany dla ilustracji sposobu korzystania ####
#### z zewnętrznych źródeł danych z użyciem API.  ####
#### Właściwe analizy można przeprowadzić na      ####
#### podstawie danych dołączonych do kodu, pocho- ####
#### dzących sprzed wyłączenia usługi i dotyczą-  ####
#### cych jednego z Autorów.                      ####
######################################################

# UWAGA: w przypadku uruchamiania z konsoli R (w trybie interaktywnym) należy wykonać polecenie 'setwd'
# w celu zmiany katalogu roboczego na katalog zawierający plik skryptu.
# Inaczej może dojsć do błędów wczytywania danych i zapisu obrazków!

# Załadowanie bibliotek
library(igraph)

# UWAGA: kod został zakomentowany, ponieważ jego wykonanie sprowokuje błędy.
# Zalecamy użycie danych przykładowych dołączonych do rozdziału.

# Załadowanie funkcji budujących sieć społeczną z pliku 'google_sg.R'
# source('01_google_sg.R')
# 
# # Dwie rundy metody kuli śniegowej dla użytkownika podanego w wywołaniu skryptu
# cat("Podaj użytkownika początkowego: ")
# user.in <- file("stdin")
# user <- readLines(user.in, n = 1)
# close(user.in)

# UWAGA DO UŻYTKOWNIKÓW WINDOWS: Skrypt może nie zadziałać z poziomu konsoli DOS.
# W takim przypadku należy ustawić poniższą zmienną na dowolnego użytkownika Twittera
# i uruchomić skrypt normalnie.
# 
user <- 'johnmyleswhite' 

# dir.create(paste("data/", user, sep = ""), showWarnings = FALSE)

user.net <- suppressWarnings(read.graph(paste("data/", user, "/", user, "_net.graphml", sep = ""), format = "graphml"))
# user.net <- twitter.snowball(user, k = 2)

# Poprawki etykiet dla Gephi
user.net  <- set.vertex.attribute(user.net, "Label", value = get.vertex.attribute(user.net, "name"))

# Next, extract the 2-core, and remove pendants generated as a result
user.cores <- graph.coreness(user.net, mode = "in")
user.clean <- subgraph(user.net, which(user.cores > 1) - 1)

# Wyodrębnienie sieci ego
user.ego <- subgraph(user.net, c(0, neighbors(user.net, user, mode = "out")))

# Dodanie do sieci danych grupowania
user.sp <- shortest.paths(user.ego)
user.hc <- hclust(dist(user.sp))

png(paste('../images/', user, '_dendrogram.png', sep=''), width=1680, height=1050)
plot(user.hc)
dev.off()

# Dodanie pierwszych 10-ciu nietrywialnych partycji HC
for(i in 2:10) {    
    user.cluster <- as.character(cutree(user.hc, k = i))
    user.cluster[1] <- "0"
    user.ego <- set.vertex.attribute(user.ego, name = paste("HC", i, sep = ""), value = user.cluster)
}

# Add k-means clustering data to network
for(i in 2:10) {
    user.km <- kmeans(dist(user.sp), centers = i)
    user.cluster <- as.character(user.km$cluster)
    user.cluster[1] <- "0"
    user.ego <- set.vertex.attribute(user.ego, name = paste("KM", i, sep = ""), value = user.cluster)
}

# Zapisanie danych w formacie GraphML
write.graph(user.net, paste("data/", user, "/", user, "_net.graphml", sep = ""), format = "graphml")
write.graph(user.clean, paste("data/", user, "/", user, "_clean.graphml", sep = ""), format = "graphml")
write.graph(user.ego, paste("data/", user, "/", user, "_ego.graphml", sep = ""), format = "graphml")
