我使用 R 编译了一个包含数千条推文的数据集。
数据集基本上如下所示:
Data <- data.frame(
X = c(1,2),
text = c("Hello @User1 #hashtag1, hello @User2 and @User3, #hashtag2", "Hello @User2 #hashtag3, hello @User1 and @User3, #hashtag4"),
screenname = c("author1", "author2")
)
现在我想将此数据集导出为 Gephi 支持的图形格式(请参阅Supported Graph Formats - Gephi)
每当“作者”在文本中提到@user 时,都应该有从作者到用户的直接链接。在上述情况下,结果应该是这样的:
作者1->@User2
作者1->@User3
作者2->@User1
作者2 -> @User3
如何操作我的数据集并将其导出为 Gephi 支持的图形格式?
如果可能,我更喜欢 GEXF 或 GraphML 格式。如果那不可能,我也可以使用 csv 或电子表格。
我整晚都在考虑解决这个问题,并朝着正确的方向迈出了几步(至少我希望如此)。但我需要你的帮助。
如上所述,我基本上有以下数据集:
Data <- data.frame(
X = c(1,2),
text = c("Hello @User1 #hashtag1, hello @User2 and @User3, #hashtag2", "Hello @User2 #hashtag3, hello @User1 and @User3, #hashtag4"),
screenname = c("author1", "author2")
)
我想将它导出为 GEXF 格式以在 Gephi 中使用它。
有一个用于将 r 数据导出到 GEXF 的 ar 包,称为 rgexf(参见https://bitbucket.org/gvegayon/rgexf/wiki/Installation)。要使用write.gexf
包的功能,我至少需要两件事:
1)网络中所有节点的矩阵(在我的例子中,作者、用户和主题标签)
2)这些节点之间的所有边的矩阵(即作者和用户之间的连接以及主题标签)。
在我的 Twitter 数据中,作者从不打印“@”,尽管他们也可以是“用户”。所以我首先要为作者添加“@”,以避免重复节点。
data$screenname <- sub("^", "@", data$screenname )
然后我需要一个矩阵,由我网络中的所有节点(即作者、用户和主题标签)组成。根据此示例,输出应如下所示:
people <- data.frame(matrix(c(1:9, '@author1', '@author2', '@user1', '@user2', '@user3', '#hashtag1', '#hashtag2', '#hashtag3', '#hashtag4'),ncol=2))
然后我需要这些节点之间所有边的矩阵。根据此示例,输出应如下所示:
relations <- data.frame(matrix(c(1,3,1,4,1,5,1,6,1,7,2,4,2,3,2,5,2,8,2,9), ncol=2, byrow=T))
最后,我只需要把这两件事放在一起:
write.gexf(people, relations)
获取以下文件:
<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.2draft" xmlns:viz="http://www.gexf.net/1.1draft/viz" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd" version="1.2">
<meta lastmodifieddate="2015-02-04">
<creator>NodosChile</creator>
<description>A graph file writing in R using "rgexf"</description>
<keywords>gexf graph, NodosChile, R, rgexf</keywords>
</meta>
<graph mode="static" defaultedgetype="undirected">
<nodes>
<node id="1" label="@author1"/>
<node id="2" label="@author2"/>
<node id="3" label="@user1"/>
<node id="4" label="@user2"/>
<node id="5" label="@user3"/>
<node id="6" label="#hashtag1"/>
<node id="7" label="#hashtag2"/>
<node id="8" label="#hashtag3"/>
<node id="9" label="#hashtag4"/>
</nodes>
<edges>
<edge id="0" source="1" target="3" weight="1"/>
<edge id="1" source="1" target="4" weight="1"/>
<edge id="2" source="1" target="5" weight="1"/>
<edge id="3" source="1" target="6" weight="1"/>
<edge id="4" source="1" target="7" weight="1"/>
<edge id="5" source="2" target="4" weight="1"/>
<edge id="6" source="2" target="3" weight="1"/>
<edge id="7" source="2" target="5" weight="1"/>
<edge id="8" source="2" target="8" weight="1"/>
<edge id="9" source="2" target="9" weight="1"/>
</edges>
</graph>
</gexf>
但是如何从上面的示例中自动提取节点和这些节点(边)之间的关系并将它们写入两个矩阵?
没有人知道如何解决我的问题吗?
我试图弄清楚如何从我的示例中提取节点(即作者、用户和主题标签)并将它们保存到 data.frame(我相信有一种更短、更优雅的方法来做到这一点!):
#extract Users and Hashtags from text, Authors from screenname (and add @ to Author-names)
Users <- stri_extract_all(Data$text, regex = "@[A-Za-z0-9]+")
Hash <- stri_extract_all(Data$text, regex = "#[A-Za-z0-9]+")
Data$screenname <- sub("^", "@", Data$screenname )
Authors <- stri_extract_all(Data$screenname, regex = "@[A-Za-z0-9]+")
# delete NAs
Users <- Users[!is.na(Users)]
Hash <- Hash[!is.na(Hash)]
# converting lists to vectors
Users <- unlist(Users)
Hash <- unlist(Hash)
Authors <- unlist(Authors)
# merging the vectors to a single vector and deleting the duplicates
nodes <- unique(c(Authors, Users, Hash))
# saving the vectors in a data.frame and giving each node a unique ID
nodes <- data.frame(matrix(c(1:length(nodes), nodes), ncol=2))
colnames(nodes) <- c("ID", "label")
但是我怎样才能为边缘构建一个 data.frame 呢?
必须有一种方法可以编写一个函数,该函数会自动检查作者是否逐行提及用户和/或主题标签,并使用作者、用户和主题标签的 ID 将结果写入新的 data.frame。每个连接都应显示在两列中:源和目标 (1,2)。