Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rmd analysis #9

Merged
merged 2 commits into from Nov 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions .gitignore
@@ -1,4 +1,4 @@
.Rproj.user
.Rhistory
.RData
.Ruserdata
.Rproj.user
.Rhistory
.RData
.Ruserdata
54 changes: 27 additions & 27 deletions README.md
@@ -1,27 +1,27 @@
# SEP Graph

A graphical representation and analysis of the Stanford Encyclopedia of Philosophy.

## Project Description

The [Stanford Encyclopedia of Philosophy][SEP] (hereafter, SEP) is a "dynamic reference work" that has a significant influence in philosophy. This project is an attempt to represent the data in the SEP graphically. The methodology of the representation is as follows:

+ Each article in the SEP is a node.
+ A directed edge connects a source and target node iff the article represented by the source contains a hyperlink to the article represented by the target.
+ Otherwise, nodes are not directly connected.

## Visualizations

[I'm hosting the visualizations for the SEP here.][1]


## Thanks

Thanks to the developers of [threejs][2], [statnet][3], [d3][4], and [igraph][5] (and everyone working on R I forgot to mention).

[SEP]: https://plato.stanford.edu
[1]: https://adamdedwards.github.io/sep-graph
[2]: https://github.com/bwlewis/rthreejs
[3]: http://statnet.csde.washington.edu/
[4]: https://github.com/d3
[5]: https://github.com/igraph
# SEP Graph
A graphical representation and analysis of the Stanford Encyclopedia of Philosophy.
## Project Description
The [Stanford Encyclopedia of Philosophy][SEP] (hereafter, SEP) is a "dynamic reference work" that has a significant influence in philosophy. This project is an attempt to represent the data in the SEP graphically. The methodology of the representation is as follows:
+ Each article in the SEP is a node.
+ A directed edge connects a source and target node iff the article represented by the source contains a hyperlink to the article represented by the target.
+ Otherwise, nodes are not directly connected.
## Visualizations
[I'm hosting the visualizations for the SEP here.][1]
## Thanks
Thanks to the developers of [threejs][2], [statnet][3], [d3][4], and [igraph][5] (and everyone working on R I forgot to mention).
[SEP]: https://plato.stanford.edu
[1]: https://adamdedwards.github.io/sep-graph
[2]: https://github.com/bwlewis/rthreejs
[3]: http://statnet.csde.washington.edu/
[4]: https://github.com/d3
[5]: https://github.com/igraph
147 changes: 147 additions & 0 deletions analysis.Rmd
@@ -0,0 +1,147 @@
---
title: "SEP Analysis"
author: "Adam Edwards"
date: "November 12, 2018"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)

list.of.packages <- c("igraph","networkD3","visNetwork","RColorBrewer")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)>0) install.packages(new.packages,repos = "http://cran.us.r-project.org")

#library(shiny)
library(igraph)
#library(threejs)
library(networkD3)
library(visNetwork)
library(RColorBrewer)
#library(extrafont)

```

## R Code

First, we need to load the data into R and create a data frame.

```{r load data}
data <- read.csv("data/fall1998_edge_list.txt", header = TRUE)
as.data.frame(data)
```

Once the data is loaded, we can create an "igraph" object. We also want to create an edge weight of 1 for each link so that we can combine multiple links into linearly weighted edges. The `simplify` function will also eliminate self-loops.

```{r create igraph}
g <- graph_from_data_frame(as.data.frame(data), directed = TRUE)
E(g)$weight <- 1
g <- simplify(g, edge.attr.comb=list(weight="sum"))
```

The igraph package has several functions that allow us to compute vertex-level and edge-level attributes for the graph. For now, we'll add node labels, degree, betweenness, and group membership using the `cluster_walktrap` function to assign group membership based on short, randow walks around the graph

```{r igraph attributes,echo=FALSE, warning=FALSE}
V(g)$label <- V(g)$name
V(g)$degree <- degree(g)
V(g)$betweenness <- betweenness(g,V(g),directed=TRUE)
#V(g)$closeness <- closeness(g,mode="all")
#V(g)$eigenvector <- eigen_centrality(g, directed = TRUE, weights=E(g)$weight)[[1]]
V(g)$group <- membership(cluster_walktrap(g))

pc <- cluster_walktrap(g)
colors <- colorRampPalette(brewer.pal(11, "Spectral"))(max(V(g)$group))
```

We can see the graph object with these new properties and the communities that the clustering algorithm has identified. One interesting feature of this data set is how the clustering algorithm identifies what I take to be the major areas that professional philosophers identify as subfields. There's no expert knowledge applied to these graphs; it's an emergent feature of how the SEP is organized.

```{r igraph}
g

communities(cluster_walktrap(g))
```

## Some Charts

We can do some pre-analysis of the graph by looking at the distributions of the different properties:

```{r pre-analysis, echo=FALSE}
hist <- hist(V(g)$degree,xlab = "Degree",main = "Degree Centrality",col=colors[3])
V(g)$name[match(tail(sort(V(g)$degree),10),V(g)$degree)]

hist <- hist(V(g)$betweenness,xlab = "Betweenness",main = "Betweenness Centrality",col=colors[9])
V(g)$name[match(tail(sort(V(g)$betweenness),10),V(g)$betweenness)]

#hist <- hist(V(g)$eigenvector,xlab = "Eigenvector",main = "Eigenvector Centrality")
#V(g)$name[match(tail(sort(V(g)$eigenvector),10),V(g)$eigenvector)]
```


## Visualizations

With igraph

```{r igraph viz, echo=FALSE}

V(g)$size <- 10
V(g)$color <- colors[V(g)$group]
E(g)$arrow.size <- .2
E(g)$edge.color <- "gray80"


plot(g,vertex.label=NA)

plot(pc,g,vertex.label=NA)

```

```{r threejs viz, echo=FALSE}

#l <- layout_with_kk(g,dim=3)
#l <- norm_coords(l, ymin=-1, ymax=1, xmin=-1, xmax=1)

#gjs <- graphjs(g,layout=l*0.2,vertex.label=V(g)$label,
# minx = NULL, maxx = 300, miny = NULL, maxy = 300, minz = NULL, maxz = 300)
#gjs
```

With NetworkD3

```{r networkd3, echo=FALSE}

gd3 <- igraph_to_networkD3(g,V(g)$group)
gd3$nodes$deg <- as.character(degree(g, v = V(g)))
gd3$nodes$btw <- as.character(betweenness(g, v = V(g), directed = TRUE))
#gd3$nodes$clo <-as.character(closeness(g, v = V(g),mode="all"))
#gd3$nodes$eig <-as.character(eigen_centrality(g, directed = TRUE)[[1]])
gd3$nodes$size <- as.character("1")
gd3$nodes$id <- row.names(gd3$nodes)



nd3 <- forceNetwork(Links = gd3$links,
Nodes = gd3$nodes,
Source = "source",
Target = "target",
Group = "group",
NodeID = "name",
Nodesize = "deg",
arrows = FALSE,
legend = FALSE,
bounded = TRUE,
opacity = 1,
opacityNoHover = .4)
nd3
```

With visNetwork

```{r visNetwork, echo=FALSE}

visIgraph(g)

```

## References/Acknowledgements

Ognyanova, K. (2018) Network visualization with R. Retrieved from www.kateto.net/network-visualization.
419 changes: 419 additions & 0 deletions analysis.html

Large diffs are not rendered by default.

34 changes: 17 additions & 17 deletions assets/sep.js
@@ -1,17 +1,17 @@

var community = 5;

window.onload = function(){document.getElementById('comm_frame').src = "pages/graphs/community_5.html";};

function prevcomm() {
if(community > 1) { community = community - 1; }
else { community = 18; }

document.getElementById('comm_frame').src = "pages/graphs/community_"+community+".html";
}

function nextcomm() {
if(community <= 19) { community = community + 1; }
else { community = 1; }
document.getElementById('comm_frame').src = "pages/graphs/community_"+community+".html";
}
var community = 5;
window.onload = function(){document.getElementById('comm_frame').src = "pages/graphs/community_5.html";};
function prevcomm() {
if(community > 1) { community = community - 1; }
else { community = 18; }
document.getElementById('comm_frame').src = "pages/graphs/community_"+community+".html";
}
function nextcomm() {
if(community <= 19) { community = community + 1; }
else { community = 1; }
document.getElementById('comm_frame').src = "pages/graphs/community_"+community+".html";
}
81 changes: 41 additions & 40 deletions assets/styles.css
@@ -1,40 +1,41 @@
h1 { font-family: 'Inconsolata', monospace; font-size: 36px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 41px; }
h2 { font-family: 'Inconsolata', monospace; font-size: 30px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 35px; }
h3 { font-family: 'Inconsolata', monospace; font-size: 27px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 32px; }

p { font-family: 'Inconsolata', monospace; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2em; }

iframe {
border: solid 2px black;
width: 80%;
padding: 20px;
display:block;
margin:auto;
}

button {
margin: 0px 15px;
border: 0;
border-radius: 8px;
padding: 10px 20px;

text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;

-webkit-transition-duration: 0.4s;
transition-duration: 0.4s;
}

button:hover {
background-color: #3A3A3A;
color: white;
}

#button-row {
width: 500px ;
margin-left: auto ;
margin-right: auto ;
padding: 20px;
}
h1 { font-family: 'Inconsolata', monospace; font-size: 36px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 41px; }
h2 { font-family: 'Inconsolata', monospace; font-size: 30px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 35px; }
h3 { font-family: 'Inconsolata', monospace; font-size: 27px; font-style: normal; font-variant: normal; font-weight: 700; line-height: 32px; }

p { font-family: 'Inconsolata', monospace; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2em; }

iframe {
border: solid 2px black;
width: 80%;
padding: 20px;
display:block;
margin:auto;
}

button {
margin: 0px 15px;
border: 0;
border-radius: 8px;
padding: 10px 20px;

text-align: center;
text-decoration: none;
display: inline-block;
font-family: 'Inconsolata', monospace;
font-size: 16px;

-webkit-transition-duration: 0.4s;
transition-duration: 0.4s;
}

button:hover {
background-color: #3A3A3A;
color: white;
}

#button-row {
width: 500px ;
margin-left: auto ;
margin-right: auto ;
padding: 20px;
}