《權(quán)力的游戲》關(guān)系網(wǎng)絡(luò)分析——基于 tidygraph 和 ggraph

!?本文摘自 Shirin's playgRound ! 本文僅為自譯轉(zhuǎn)載杖小,任何觀點(diǎn)都不代表個(gè)人觀點(diǎn)饮焦!

不久之前,我曾經(jīng)做過(guò)一個(gè)關(guān)于冰與火之歌人物關(guān)系的圖譜分析窍侧。在這個(gè)分析中县踢,我發(fā)現(xiàn)史塔克家族(尤其是Ned 和三傻[皮一下很開(kāi)心])和蘭尼斯特家族(尤其是Tyrion),是權(quán)利的游戲中伟件,最主要的家族連接點(diǎn)硼啤。他們連接著很多故事線,也是整個(gè)故事的中心點(diǎn)斧账。

在之前的 PO 文中谴返,我使用了 igraphl 來(lái)描繪和計(jì)算關(guān)系矩陣。

但是現(xiàn)在有兩個(gè)更好的包可以完成整個(gè)關(guān)系分析:?tidyverse:?tidygraph?和?ggraph咧织。

所以這篇文章將使用這兩個(gè)包來(lái)制作 冰與火之歌/權(quán)利的游戲 的任務(wù)關(guān)系分析圖嗓袱。(內(nèi)容基于冰與火這個(gè)著作而非電視節(jié)目)

社會(huì)關(guān)系分析 或者社會(huì)網(wǎng)絡(luò)分析能帶來(lái)什么?

關(guān)系分析能發(fā)現(xiàn)和挖掘社會(huì)或者專(zhuān)業(yè)領(lǐng)域社交網(wǎng)絡(luò)中的關(guān)系习绢。我們通常會(huì)問(wèn):每個(gè)網(wǎng)絡(luò)中的人(節(jié)點(diǎn))有多少關(guān)系連接(邊)渠抹?

誰(shuí)是連接數(shù)最多(最重要,最有影響力)的人闪萄?

緊密聯(lián)系的人是否導(dǎo)致大的集群的存在梧却?

是否有關(guān)鍵人物在集群之間擁有重要作用?

這些問(wèn)題的答案通嘲苋ィ可以幫助我們理解放航,人類(lèi)是怎么在社會(huì)中交流和互動(dòng)。

所以圆裕,我們?cè)趺床拍苷业皆诰W(wǎng)絡(luò)中最重要的角色广鳍?簡(jiǎn)單來(lái)說(shuō),當(dāng)一個(gè)人擁有最多關(guān)系或最多與之相連的人的時(shí)候吓妆,其重要性不言則明赊时。同時(shí)也有一些其他的屬性可以幫助我們尋找這些關(guān)鍵人物,例如節(jié)點(diǎn)中心度(node centrality).

冰與火之歌角色關(guān)系圖

library(readr)? ???# fast reading of csv files

library(tidyverse) # tidy data analysis

library(tidygraph) # tidy graph analysis

library(ggraph)? ? # for plotting

數(shù)據(jù)

數(shù)據(jù)來(lái)源于 Github Repository耿战,Andrew Beveridge:

Character Interaction Networks for George R. R. Martin’s “A Song of Ice and Fire” saga These networks were created by connecting two characters whenever their names (or nicknames) appeared within 15 words of one another in one of the books in “A Song of Ice and Fire.” The edge weight corresponds to the number of interactions. You can use this data to explore the dynamics of the Seven Kingdoms using network science techniques. For example, community detection finds coherent plotlines. Centrality measures uncover the multiple ways in which characters play important roles in the saga.

Andrew 已經(jīng)做過(guò)一個(gè)關(guān)于冰與火之歌角色關(guān)系的分析蛋叼,如果你感興趣焊傅,也可以去他的網(wǎng)站瀏覽他的結(jié)論https://networkofthrones.wordpress.com

這里我不想復(fù)制他的分析剂陡,而是希望展示如何使用 tidygraph 和 ggraph狈涮。所以我并不會(huì)完全使用他的數(shù)據(jù)。

path <- "/Users/shiringlander/Documents/Github/Data/asoiaf/data/"

files <- list.files(path = path, full.names = TRUE)

files

##??[1] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-all-edges.csv"

##??[2] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-all-nodes.csv"

##??[3] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book1-edges.csv"?

##??[4] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book1-nodes.csv"?

##??[5] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book2-edges.csv"?

##??[6] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book2-nodes.csv"?

##??[7] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book3-edges.csv"?

##??[8] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book3-nodes.csv"?

##??[9] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book4-edges.csv"?

## [10] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book4-nodes.csv"?

## [11] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book45-edges.csv"

## [12] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book45-nodes.csv"

## [13] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book5-edges.csv"?

## [14] "/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book5-nodes.csv"

全書(shū)角色

首先要使用的是全書(shū)角色互動(dòng)關(guān)系的數(shù)據(jù)鸭栖。這里我不打算使用節(jié)點(diǎn)的數(shù)據(jù)歌馍,因?yàn)槲野l(fā)現(xiàn)關(guān)系(edge)的名稱(chēng)標(biāo)記已經(jīng)足夠用來(lái)標(biāo)注。當(dāng)然晕鹊,如果你希望使用更好的名詞標(biāo)識(shí)松却,可以使用節(jié)點(diǎn)數(shù)據(jù)。

cooc_all_edges <- read_csv(files[1])

因?yàn)闀?shū)中有太多角色溅话,而且很多都是小角色晓锻,所以我抽出前100位互動(dòng)關(guān)系較多的角色。關(guān)系都是無(wú)向關(guān)系飞几,所以沒(méi)有冗余的Source-Target combination

main_ch <- cooc_all_edges %>%

select(-Type) %>%

gather(x, name, Source:Target) %>%

group_by(name) %>%

summarise(sum_weight = sum(weight)) %>%

ungroup()

main_ch_l <- main_ch %>%

arrange(desc(sum_weight)) %>%

top_n(100, sum_weight)

main_ch_l

## # A tibble: 100 x 2

##? ? name? ?? ?? ?? ?? ?sum_weight

##

##??1 Tyrion-Lannister? ?? ?? ?2873

##??2 Jon-Snow? ?? ?? ?? ?? ???2757

##??3 Cersei-Lannister? ?? ?? ?2232

##??4 Joffrey-Baratheon? ?? ???1762

##??5 Eddard-Stark? ?? ?? ?? ? 1649

##??6 Daenerys-Targaryen? ?? ? 1608

##??7 Jaime-Lannister? ?? ?? ? 1569

##??8 Sansa-Stark? ?? ?? ?? ???1547

##??9 Bran-Stark? ?? ?? ?? ?? ?1508

## 10 Robert-Baratheon? ?? ?? ?1488

## # ... with 90 more rows

cooc_all_f <- cooc_all_edges %>%

filter(Source %in% main_ch_l$name & Target %in% main_ch_l$name)

tidygraph 和 ggraph

兩個(gè)工具包都來(lái)自于?Thomas Lin Pedersen:

With tidygraph I set out to make it easier to get your data into a graph and perform common transformations on it, but the aim has expanded since its inception. The goal of tidygraph is to empower the user to formulate complex questions regarding relational data as simple steps, thus enabling them to retrieve insights directly from the data itself. The central idea this all boils down to is this: you don’t have to plot a network to understand it. While I absolutely love the field of network visualisation, it is in many ways overused in data science — especially when it comes to extracting knowledge from a network. Just as you don’t need a plot to tell you which car in a dataset is the fastest, you don’t need a plot to tell you which pair of friends are the closest. What you do need, instead of a plot, is a tool that allow you to formulate your question into a logic sequence of operations. For many people in the world of rectangular data, this tool is increasingly dplyr (and friends), and I do hope that tidygraph can take on the same role in the world of relational data.?https://www.data-imaginist.com/2018/tidygraph-1-1-a-tidy-hope/

首先砚哆,將邊的表格轉(zhuǎn)換為 tbl_graph 格式。這里使用 tidygrpah 中的as_tbl_graph()函數(shù)屑墨,其可以輸入 data.frame,matrix,dendrogram,igraph,etc.

Underneath the hood of tidygraph lies the well-oiled machinery of igraph, ensuring efficient graph manipulation. Rather than keeping the node and edge data in a list and creating igraph objects on the fly when needed, tidygraph subclasses igraph with the tbl_graph class and simply exposes it in a tidy manner. This ensures that all your beloved algorithms that expects igraph objects still works with tbl_graph objects. Further, tidygraph is very careful not to override any of igraphs exports so the two packages can coexist quite happily.?https://www.data-imaginist.com/2018/tidygraph-1-1-a-tidy-hope/

有很多 node ranking 的選擇(可以去?node_rank查看詳細(xì)列表)躁锁。我這里嘗試TSP 解算器最小化哈密頓回路的方法?Minimize hamiltonian path length using a travelling salesperson solver):

as_tbl_graph(cooc_all_f, directed = FALSE) %>%

activate(nodes) %>%?

mutate(n_rank_trv = node_rank_traveller()) %>%

arrange(n_rank_trv)

## # A tbl_graph: 100 nodes and 798 edges

## #

## # An undirected simple graph with 1 component

## #

## # Node Data: 100 x 2 (active)

##? ?name? ?? ?? ?? ?? ?? ?? ?? ?? ? n_rank_trv

##

## 1 Janos-Slynt? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?1

## 2 Aemon-Targaryen-(Maester-Aemon)? ?? ?? ? 2

## 3 Jeor-Mormont? ?? ?? ?? ?? ?? ?? ?? ?? ???3

## 4 Samwell-Tarly? ?? ?? ?? ?? ?? ?? ?? ?? ? 4

## 5 Qhorin-Halfhand? ?? ?? ?? ?? ?? ?? ?? ???5

## 6 Ygritte? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 6

## # ... with 94 more rows

## #

## # Edge Data: 798 x 5

##? ? from? ? to Type? ?? ?? ? id weight

##?

## 1? ???2? ? 75 Undirected? ? 43? ?? ?7

## 2? ???2? ? 76 Undirected? ? 44? ?? ?4

## 3? ???2? ? 73 Undirected? ? 52? ?? ?3

## # ... with 795 more rows

Centrality 中心度

中心度用來(lái)表示節(jié)點(diǎn)入度和出度的數(shù)量。高度中心化的網(wǎng)絡(luò)中卵史,且之有較少的節(jié)點(diǎn)擁有較大數(shù)量的邊战转。低度中心化的網(wǎng)絡(luò)中擁有較多的節(jié)點(diǎn),同時(shí)節(jié)點(diǎn)度相對(duì)小而平均以躯。而節(jié)點(diǎn)中心度衡量了節(jié)點(diǎn)在網(wǎng)絡(luò)中的重要程度槐秧。

This version adds 19(!) new ways to define the notion of centrality along with a manual version where you can mix and match different distance measures and summation strategies opening up the world to even more centrality scores. All of this wealth of centrality comes from the netrankr package that provides a framework for defining and calculating centrality scores. If you use centrality measures somewhere in your analysis I cannot recommend the vignettes provided by netrankr enough as they provide a fundamental intuition about the nature of such measures and how they can/should be used.?https://www.data-imaginist.com/2018/tidygraph-1-1-a-tidy-hope/

可以使用?centrality查看所有關(guān)于中心度計(jì)算的所有方法。 這里我們使用centrality_degree()忧设。

## # A tbl_graph: 100 nodes and 798 edges

## #

## # An undirected simple graph with 1 component

## #

## # Node Data: 100 x 2 (active)

##? ?name? ?? ?? ?? ???neighbors

##

## 1 Tyrion-Lannister? ?? ???54.

## 2 Cersei-Lannister? ?? ???49.

## 3 Joffrey-Baratheon? ?? ? 49.

## 4 Robert-Baratheon? ?? ???47.

## 5 Jaime-Lannister? ?? ?? ?45.

## 6 Sansa-Stark? ?? ?? ?? ? 44.

## # ... with 94 more rows

## #

## # Edge Data: 798 x 5

##? ? from? ? to Type? ?? ?? ? id weight

##?

## 1? ? 41? ? 42 Undirected? ? 43? ?? ?7

## 2? ? 41? ? 60 Undirected? ? 44? ?? ?4

## 3? ? 41? ? 63 Undirected? ? 52? ?? ?3

## # ... with 795 more rows


組和聚類(lèi) Grouping and clustring

Another common operation is to group nodes based on the graph topology, sometimes referred to as community detection based on its commonality in social network analysis. All clustering algorithms from igraph is available in tidygraph using the group_* prefix. All of these functions return an integer vector with nodes (or edges) sharing the same integer being grouped together. https://www.data-imaginist.com/2017/introducing-tidygraph/

可以使用?group_graph查看所有分組和聚類(lèi)的方法色鸳。這里我使用 group_infomap():Group nodes by minimizing description length using.

as_tbl_graph(cooc_all_f, directed = FALSE) %>%

activate(nodes) %>%?

mutate(group = group_infomap()) %>%

arrange(-group)

## # A tbl_graph: 100 nodes and 798 edges

## #

## # An undirected simple graph with 1 component

## #

## # Node Data: 100 x 2 (active)

##? ?name? ?? ?? ?? ???group

##?

## 1 Arianne-Martell? ?? ? 7

## 2 Doran-Martell? ?? ?? ?7

## 3 Davos-Seaworth? ?? ???6

## 4 Melisandre? ?? ?? ?? ?6

## 5 Selyse-Florent? ?? ???6

## 6 Stannis-Baratheon? ???6

## # ... with 94 more rows

## #

## # Edge Data: 798 x 5

##? ? from? ? to Type? ?? ?? ? id weight

##?

## 1? ? 32? ? 33 Undirected? ? 43? ?? ?7

## 2? ? 32? ? 34 Undirected? ? 44? ?? ?4

## 3? ? 32? ? 36 Undirected? ? 52? ?? ?3

## # ... with 795 more rows

復(fù)制代碼

查詢(xún)節(jié)點(diǎn)類(lèi)型(query node type)

我們也可以查詢(xún)節(jié)點(diǎn)類(lèi)型,使用?node_types 來(lái)查看所有內(nèi)容见转。

These functions all lets the user query whether each node is of a certain type. All of the functions returns a logical vector indicating whether the node is of the type in question. Do note that the types are not mutually exclusive and that nodes can thus be of multiple types.

這里我使用 node_is_center 和 node_is_keyplayer 來(lái)查詢(xún)圖中前10名重要關(guān)鍵人物命雀。 你也可以在 influenceR 包中找到更多關(guān)于 node_is_keyplayer 函數(shù)的內(nèi)容。

The “Key Player” family of node importance algorithms (Borgatti 2006) involves the selection of a metric of node importance and a combinatorial optimization strategy to choose the set S of vertices of size k that maximize that metric. This function implements KPP-Pos, a metric intended to identify k nodes which optimize resource diffusion through the net … https://www.data-imaginist.com/2017/introducing-tidygraph/

as_tbl_graph(cooc_all_f, directed = FALSE) %>%

activate(nodes) %>%?

mutate(dist_to_center = node_distance_to(node_is_center()))

## # A tbl_graph: 100 nodes and 798 edges

## #

## # An undirected simple graph with 1 component

## #

## # Node Data: 100 x 2 (active)

##? ?name? ?? ?? ?? ?? ?? ?? ?? ?? ? dist_to_center

##

## 1 Aemon-Targaryen-(Maester-Aemon)? ?? ?? ?? ? 1.

## 2 Aeron-Greyjoy? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 2.

## 3 Aerys-II-Targaryen? ?? ?? ?? ?? ?? ?? ?? ???1.

## 4 Alliser-Thorne? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?1.

## 5 Arianne-Martell? ?? ?? ?? ?? ?? ?? ?? ?? ???2.

## 6 Arya-Stark? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 1.

## # ... with 94 more rows

## #

## # Edge Data: 798 x 5

##? ? from? ? to Type? ?? ?? ? id weight

##?

## 1? ???1? ???4 Undirected? ? 43? ?? ?7

## 2? ???1? ? 13 Undirected? ? 44? ?? ?4

## 3? ???1? ? 28 Undirected? ? 52? ?? ?3

## # ... with 795 more rows

復(fù)制代碼

Edge betweeness

和節(jié)點(diǎn)的指標(biāo)一樣斩箫,邊或者關(guān)系上吏砂,我們也可以獲得很多指標(biāo)。Betweeness 就是用來(lái)表示任意兩個(gè)節(jié)點(diǎn)間最短路徑的關(guān)系指標(biāo)乘客。[皮一下:小世界理論狐血?]。tidygraph 中可以查看edge_type的詳細(xì)內(nèi)容

as_tbl_graph(cooc_all_f, directed = FALSE) %>%

activate(edges) %>%?

mutate(centrality_e = centrality_edge_betweenness())

## # A tbl_graph: 100 nodes and 798 edges

## #

## # An undirected simple graph with 1 component

## #

## # Edge Data: 798 x 6 (active)

##? ? from? ? to Type? ?? ?? ? id weight centrality_e

##

## 1? ???1? ???4 Undirected? ? 43? ?? ?7? ?? ?? ?1.00

## 2? ???1? ? 13 Undirected? ? 44? ?? ?4? ?? ???30.2?

## 3? ???1? ? 28 Undirected? ? 52? ?? ?3? ?? ???42.1?

## 4? ???1? ? 32 Undirected? ? 53? ???20? ?? ?? ?0.

## 5? ???1? ? 34 Undirected? ? 54? ?? ?5? ?? ???35.2?

## 6? ???1? ? 41 Undirected? ? 56? ?? ?5? ?? ???18.9?

## # ... with 792 more rows

## #

## # Node Data: 100 x 1

##? ?name

##

## 1 Aemon-Targaryen-(Maester-Aemon)

## 2 Aeron-Greyjoy

## 3 Aerys-II-Targaryen?

## # ... with 97 more rows

復(fù)制代碼

完整的內(nèi)容

讓我們組合起來(lái)之前的東西:

cooc_all_f_graph <- as_tbl_graph(cooc_all_f, directed = FALSE) %>%

mutate(n_rank_trv = node_rank_traveller(),

neighbors = centrality_degree(),

group = group_infomap(),

center = node_is_center(),

dist_to_center = node_distance_to(node_is_center()),

keyplayer = node_is_keyplayer(k = 10)) %>%

activate(edges) %>%?

filter(!edge_is_multiple()) %>%

??mutate(centrality_e = centrality_edge_betweenness())

復(fù)制代碼

我們也可以將節(jié)點(diǎn)和邊的表轉(zhuǎn)換為tibble:

cooc_all_f_graph %>%

activate(nodes) %>% # %N>%

as.tibble()

## # A tibble: 100 x 7

##? ? name? ?? ?? ?n_rank_trv neighbors group center dist_to_center keyplayer

##?

##??1 Aemon-Targa…? ?? ?? ?45? ?? ? 13.? ???2 FALSE? ?? ?? ?? ???1. FALSE?

##??2 Aeron-Greyj…? ?? ?? ?21? ?? ???5.? ???5 FALSE? ?? ?? ?? ???2. FALSE?

##??3 Aerys-II-Ta…? ?? ?? ?11? ?? ? 12.? ???1 FALSE? ?? ?? ?? ???1. FALSE?

##??4 Alliser-Tho…? ?? ?? ?48? ?? ? 13.? ???2 FALSE? ?? ?? ?? ???1. FALSE?

##??5 Arianne-Mar…? ?? ?? ?29? ?? ???4.? ???7 FALSE? ?? ?? ?? ???2. FALSE?

##??6 Arya-Stark? ?? ?? ???79? ?? ? 37.? ???1 FALSE? ?? ?? ?? ???1. FALSE?

##??7 Asha-Greyjoy? ?? ?? ?20? ?? ???7.? ???5 FALSE? ?? ?? ?? ???1. FALSE?

##??8 Balon-Greyj…? ?? ?? ?18? ?? ? 11.? ???5 FALSE? ?? ?? ?? ???2. FALSE?

##??9 Barristan-S…? ?? ?? ?54? ?? ? 23.? ???3 FALSE? ?? ?? ?? ???1. FALSE?

## 10 Belwas? ?? ?? ?? ?? ?52? ?? ???6.? ???3 FALSE? ?? ?? ?? ???2. FALSE?

## # ... with 90 more rows

cooc_all_f_graph %>%

activate(edges) %>% # %E>%

as.tibble()

## # A tibble: 798 x 6

##? ???from? ? to Type? ?? ?? ? id weight centrality_e

##?

##??1? ???1? ???4 Undirected? ? 43? ?? ?7? ?? ?? ?1.00

##??2? ???1? ? 13 Undirected? ? 44? ?? ?4? ?? ???30.2?

##??3? ???1? ? 28 Undirected? ? 52? ?? ?3? ?? ???42.1?

##??4? ???1? ? 32 Undirected? ? 53? ???20? ?? ?? ?0.

##??5? ???1? ? 34 Undirected? ? 54? ?? ?5? ?? ???35.2?

##??6? ???1? ? 41 Undirected? ? 56? ?? ?5? ?? ???18.9?

##??7? ???1? ? 42 Undirected? ? 57? ???25? ?? ?? ?0.

##??8? ???1? ? 48 Undirected? ? 58? ? 110? ?? ?? ?0.

##??9? ???1? ? 58 Undirected? ? 60? ?? ?5? ?? ???24.5?

## 10? ???1? ? 71 Undirected? ? 62? ?? ?5? ?? ???17.0?

## # ... with 788 more rows

復(fù)制代碼


ggraph 畫(huà)圖

ggraph is an extension of ggplot2 aimed at supporting relational data structures such as networks, graphs, and trees. While it builds upon the foundation of ggplot2 and its API it comes with its own self-contained set of geoms, facets, etc., as well as adding the concept of layouts to the grammar. https://github.com/thomasp85/ggraph

首先易核,我需要定義 一層 layout, 有很多 options for layout,這里我要使用?Fruchterman-Reingold?algorithm匈织。

layout <- create_layout(cooc_all_f_graph,?

? ?? ?? ?? ?? ?? ?? ?? ?layout = "fr")

復(fù)制代碼

剩下的工作就比較類(lèi)似于 ggplot2的函數(shù),只不過(guò)我們會(huì)用到特殊的函數(shù)來(lái)繪制網(wǎng)絡(luò)。比如 geom_edge_density 可以用來(lái)畫(huà)高密度的陰影區(qū)域缀匕,geom_edge_lin 來(lái)連接節(jié)點(diǎn)纳决,geom_node_point 來(lái)繪制節(jié)點(diǎn),同時(shí) geom_node_text 用來(lái)標(biāo)注節(jié)點(diǎn)名稱(chēng)乡小。 你也可以在手冊(cè)中找到更詳細(xì)的內(nèi)容阔加。

graph(layout) +?

geom_edge_density(aes(fill = weight)) +

geom_edge_link(aes(width = weight), alpha = 0.2) +?

geom_node_point(aes(color = factor(group)), size = 10) +

geom_node_text(aes(label = name), size = 8, repel = TRUE) +

scale_color_brewer(palette = "Set1") +

theme_graph() +

labs(title = "A Song of Ice and Fire character network",

? ?? ?? ?subtitle = "Nodes are colored by group")

復(fù)制代碼


Interestingly, many of the groups reflect the narrative perfectly: the men from the Night’s Watch are grouped together with the Wildlings, Stannis, Davos, Selyse and Melisandre form another group, the Greyjoys, Bran’s group in Winterfell before they left for the North, Dany and her squad and the Martells (except for Quentyn, who “belongs” to Dany – just like in the books ;-)). The big group around the remaining characters is the only one that’s not split up very well.

下圖使用了?RColorBrewer?palette “Set1”:


該圖中我畫(huà)出了最中心的人物,同時(shí)節(jié)點(diǎn)的大小表示各個(gè)節(jié)點(diǎn)到中心的距離满钟。書(shū)中最重要的兩個(gè)角色就是Robert 和 Tyrion. (馬丁大爺反正說(shuō)他最喜歡小惡魔【笑】)


各個(gè)書(shū)中的角色

后面該作者也做了各個(gè)書(shū)中的角色的網(wǎng)絡(luò)圖胜榔。

The second data set I am going to use is a comparison of character interactions in the five books.

A little node on the side:?My original plan was to loop over the separate edge files for each book, concatenate them together with the information from which book they are and then plot them via faceting. This turned out to be a bad solution because I wanted to show the different key-players in each of the five books. So, instead of using one joined graph, I created separate graphs for every book and used the bind_graphs() and facet_nodes() functions to plot them together.

for (i in 1:5) {

cooc <- read_csv(paste0("/Users/shiringlander/Documents/Github/Data/asoiaf/data//asoiaf-book", i, "-edges.csv")) %>%

mutate(book = paste0("book_", i)) %>%

filter(Source %in% main_ch_l$name & Target %in% main_ch_l$name)

assign(paste0("coocs_book_", i), cooc)

}

The concepts are the same as above, here I want to know the key-players in each book:

cooc_books_1_graph <- as_tbl_graph(coocs_book_1, directed = FALSE) %>%

mutate(book = "Book 1: A Game of Thrones",

keyplayer = node_is_keyplayer(k = 10))

cooc_books_2_graph <- as_tbl_graph(coocs_book_2, directed = FALSE) %>%

mutate(book = "Book 2: A Clash of Kings",

keyplayer = node_is_keyplayer(k = 10))

cooc_books_3_graph <- as_tbl_graph(coocs_book_3, directed = FALSE) %>%

mutate(book = "Book 3: A Storm of Swords",

keyplayer = node_is_keyplayer(k = 10))

cooc_books_4_graph <- as_tbl_graph(coocs_book_4, directed = FALSE) %>%

mutate(book = "Book 4: A Feast for Crows",

keyplayer = node_is_keyplayer(k = 10))

cooc_books_5_graph <- as_tbl_graph(coocs_book_5, directed = FALSE) %>%

mutate(book = "Book 5: A Dance with Dragons",

keyplayer = node_is_keyplayer(k = 10))

And let’s combine and plot the key-players:

cooc_books_1_graph %>%?

bind_graphs(cooc_books_2_graph)??%>%

bind_graphs(cooc_books_3_graph)??%>%

bind_graphs(cooc_books_4_graph)??%>%

bind_graphs(cooc_books_5_graph)??%>%

ggraph(layout = "fr") +?

facet_nodes( ~ book, scales = "free", ncol = 1) +

geom_edge_density(aes(fill = weight)) +

geom_edge_link(aes(edge_width = weight), alpha = 0.2) +?

geom_node_point(aes(color = factor(keyplayer)), size = 3) +

geom_node_text(aes(label = name), color = "black", size = 3, repel = TRUE) +

theme_graph() +

? ? scale_colour_manual(values = c(cols[2], cols[1]))

復(fù)制代碼

全文摘自: https://www.r-bloggers.com/another-game-of-thrones-network-analysis-this-time-with-tidygraph-and-ggraph/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+RBloggers+%28R+bloggers%29

作者:?Dr. Shirin Glander

僅做分享討論

:)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市湃番,隨后出現(xiàn)的幾起案子夭织,更是在濱河造成了極大的恐慌,老刑警劉巖吠撮,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摔癣,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡纬向,警方通過(guò)查閱死者的電腦和手機(jī)择浊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)逾条,“玉大人琢岩,你說(shuō)我怎么就攤上這事∈χ” “怎么了担孔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吃警。 經(jīng)常有香客問(wèn)我糕篇,道長(zhǎng),這世上最難降的妖魔是什么酌心? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任拌消,我火速辦了婚禮,結(jié)果婚禮上安券,老公的妹妹穿的比我還像新娘墩崩。我一直安慰自己,他們只是感情好侯勉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布鹦筹。 她就那樣靜靜地躺著,像睡著了一般址貌。 火紅的嫁衣襯著肌膚如雪铐拐。 梳的紋絲不亂的頭發(fā)上徘键,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音遍蟋,去河邊找鬼吹害。 笑死,一個(gè)胖子當(dāng)著我的面吹牛匿值,可吹牛的內(nèi)容都是我干的赠制。 我是一名探鬼主播赂摆,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼挟憔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了烟号?” 一聲冷哼從身側(cè)響起绊谭,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汪拥,沒(méi)想到半個(gè)月后达传,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迫筑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宪赶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脯燃。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搂妻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辕棚,到底是詐尸還是另有隱情欲主,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布逝嚎,位于F島的核電站扁瓢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏补君。R本人自食惡果不足惜引几,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挽铁。 院中可真熱鬧她紫,春花似錦、人聲如沸屿储。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)够掠。三九已至民褂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赊堪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工面殖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哭廉。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓脊僚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親遵绰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辽幌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 我是一個(gè)80末乌企,今年29歲,大學(xué)畢業(yè)5年成玫,正常的未婚的大概被催過(guò)至少5年婚了加酵,結(jié)婚的在被催生,一胎結(jié)束還有...
    麥兜小姐閱讀 1,903評(píng)論 22 13
  • 嗨 大家好哭当,我是女人課堂主播學(xué)員文芷猪腕。我和我先生結(jié)婚7年,我們之間從互撕后來(lái)到鬧著要離婚到現(xiàn)在心中卻都有彼此钦勘,我能...
    文芷陳閱讀 151評(píng)論 0 0
  • Windows系統(tǒng)下自帶計(jì)算文件散列值的方法陋葡,來(lái)自這里。certutil -hashfile yourfilena...
    環(huán)零弦閱讀 186評(píng)論 0 0
  • 第一次有認(rèn)真回顧大學(xué)四年的這個(gè)念頭个盆,是在從廣州市場(chǎng)調(diào)研返程的路上脖岛。 前排兩個(gè)聊人生的朋友讓我懷疑自己走錯(cuò)了片長(zhǎng)。他...
    tommyli_2d4a閱讀 316評(píng)論 0 1