笔者是《权力的游戏》忠实粉丝,而随着第八季的开播,我相信整部剧也将迎来高潮,人类要跟亡者军团进行交战了,到底是亡者军队击溃人类,还是人类打败亡者军队呢?王座到底会花落谁家? 让我们用R语言来研究一下其中的奥秘。
首先我们需要下载权游中人物的数据,可以到https://github.com/fabrikate/dataGOT和https://en.wikipedia.org/wiki/List_of_Game_of_Thrones_characters去下载,如果链接不能打开,可以使用链接:https://pan.baidu.com/s/1CkEL35dsCRWvXNJ6nXJdhg 提取码:4lxi来获取本文中的相关材料。
如果读者使用的是原始链接,会看到character-predictions.csv、character-deaths.csv、battles.csv三个文件,使用百度网盘下载的读者还会看到nodes.csv和net1.csv两个文件。其中在原始材料中character-predictions.csv是最重要的文件。
这里面有角色的姓名,家庭以及父母、配偶、子女、家族等人物关系。那么我们就要梳理这其中的人物关系。
首先载入数据
#载入数据,注意修改文件路径
battle<-read.csv("battles.csv")
deaths<-read.csv("character-deaths.csv")
pred<-read.csv("character-predictions.csv")
建立人物关系,以亲子关系为例
#以孩子关系为例,找出prediction表中的亲子关系
child_of <- data.frame(name = pred$name[grepl("son of | daughter of", pred$name)],
stringsAsFactors = FALSE)
child_of$child_of <- ifelse(grepl("daughter", child_of$name), paste(gsub("(.* daughter of )(.*)", "\\2", child_of$name),
gsub("(.* )(.*)( daughter of.*)", "\\2", child_of$name)), paste(gsub("(.* son of )(.*)", "\\2", child_of$name),
gsub("(.* )(.*)( son of.*)", "\\2", child_of$name)))
child_of[child_of$name == "not clear", "child_of"] <- "notclear"
最近visNetwork的R语言版本已经发布了,这是一款利用JS框架来渲染的专门用来展示人物关系的工具。他的安装非常简单install.packages('visNetwork')即可完成安装。
它的用法也非常简单,定义nodes和edge就可以完成,其中node就是每个人物的定义,而edge则是表示人物之间关系的。示例如下:
首先先成随机的人物(nodes) ,其中label标签对应人物名称,group对应人物家族,value对应节点大小,shape对应节点开关,title是代码鼠标经过时显示的tip,color代表颜色,shadow代码是否有阴影。
nodes <- data.frame(id = 1:10,
label = paste("Node", 1:10), # add labels on nodes
group = c("GrA", "GrB"), # add groups on nodes
value = 1:10, # size adding value
shape = c("square", "triangle", "box", "circle", "dot", "star",
"ellipse", "database", "text", "diamond"), # control shape of nodes
title = paste0("", 1:10,"
Node !
"), # tooltip (html or character)
color = c("darkred", "grey", "orange", "darkblue", "purple"),# color
shadow = c(FALSE, TRUE, FALSE, TRUE, TRUE)) # shadow
head(nodes)
## id label group value shape title color shadow
## 1 1 Node 1 GrA 1 square 1
Node !
darkred FALSE
## 2 2 Node 2 GrB 2 triangle 2
Node !
grey TRUE
## 3 3 Node 3 GrA 3 box 3
Node !
orange FALSE
## 4 4 Node 4 GrB 4 circle 4
Node !
darkblue TRUE
## 5 5 Node 5 GrA 5 dot 5
Node !
purple TRUE
## 6 6 Node 6 GrB 6 star 6
Node !
darkred FALSE
然后生成随着的人物关系(edges),其中from,to代表连线的两个节点,label代码连线的名称,length代码连线的taya,arrow代表简头的方向,title代表鼠标经过时出现的tip
edges <- data.frame(from = sample(1:10, 8), to = sample(1:10, 8),
label = paste("Edge", 1:8), # add labels on edges
length = c(100,500), # length
arrows = c("to", "from", "middle", "middle;to"), # arrows
dashes = c(TRUE, FALSE), # dashes
title = paste("Edge", 1:8), # tooltip (html or character)
smooth = c(FALSE, TRUE), # smooth
shadow = c(FALSE, TRUE, FALSE, TRUE)) # shadow
head(edges)
## from to label length arrows dashes title smooth shadow
## 1 9 9 Edge 1 100 to TRUE Edge 1 FALSE FALSE
## 2 4 2 Edge 2 500 from FALSE Edge 2 TRUE TRUE
## 3 1 3 Edge 3 100 middle TRUE Edge 3 FALSE FALSE
## 4 3 7 Edge 4 500 middle;to FALSE Edge 4 TRUE TRUE
## 5 10 6 Edge 5 100 to TRUE Edge 5 FALSE FALSE
## 6 2 8 Edge 6 500 from FALSE Edge 6 TRUE TRUE
最后就可以生成社交网络了
visNetwork(nodes, edges, width = "100%")
接下来,我们就可以来绘制r语言的人物关系图了,刚刚我们已经介绍了如何使用语言来进行数据处理了,这里我们不加赘述,读者可以直接使用我在百度去的分享,直接读入相关数据即可,当然也可以研究一下如何利用权游的官方数据来生成角色和角色之间的关系信息.
library(visNetwork)
edges =read.csv('f:/net1.csv')
nodes=read.csv('f:/characters1.csv')
View(edges)
View(nodes)
先来讲一下角色中的关系信息character1.csv,其内容如下:其中的各列我刚刚都已经介绍过了,只是id一项呢是节点的唯一标识(key),其余不需要再说明了.
再来看人物关系图net1.csv内容如下,其中from和to代表了characters当中的人物id值,其余刚刚也介绍过了.
最后使用visNetwork(nodes, edges, width = "100%")来大功靠成了,注意生成的是个动态的js网页,你就可以从任意一个人物切换,走入他们的世界了