我正在进行社交网络分析,并使用两个数据帧。数据帧A(或"节点"(具有与网络的每个节点相关的信息(即id和名称(。数据帧B(或"链路"(有两列:;从";以及";至";这基本上显示了节点是如何在它们之间连接的。每一行表示一个链接";从";一个节点";至";另一个。我想使用包networkD3来可视化网络,但它有一些要求:id应该从零开始,并且必须是连续的(0,1,2等(。因为我的节点和链接是来自较大数据库的随机子集,所以它们不是连续的。我把";节点";数据帧,并创建了一个从零开始并具有连续数字的新列(new_id(。但现在,我不知道如何更新"链接";基于new_id的数据帧当前,我正在转换";链接";数据帧转换为字符,然后使用CCD_ 1包对其进行重新估价。但我需要为更大的数据集做这件事。我正在复制我现在拥有的两个数据帧的样本:
set.seed(10)
nodes_df <- data.frame(id = c(1,3,5,6,8,10),
name = c("Agriculture", "Agriculture_in_Mesoamerica", "Agriculture_in_ancient_Greece",
"Agriculture_in_ancient_Rome", "Agriculture_in_India", "Agriculture_in_China"),
new_id = seq(0,5))
links_df <- data.frame(from = c(3,3,5,6,8,10),
to = c(1,5,6,8,10,3))
总之,我需要更新links_df中的值,以对应于nodes_df的new_id值。
事先非常感谢。我希望我已经足够清楚了。致问候,
在base
中,您只需要使用merge
并提取所需的列
links_df$new_to <- merge(links_df, nodes_df,
by.x = "to", by.y = "id",
all.x = TRUE)$new_id
links_df$new_from <- merge(links_df, nodes_df,
by.x = "from", by.y = "id",
all.x = TRUE)$new_id
links_df <- links_df[,c(1,2,4,3)] # Reordering columns
links_df
from to new_from new_to
1 3 1 1 0
2 3 5 1 1
3 5 6 2 2
4 6 8 3 3
5 8 10 4 4
6 10 3 5 5
合并或联接的替代方案可以是使用recode
。一个解决方案(基于tidyverse(可以如下所示。
library(dplyr)
library(tibble)
swap <- deframe(tibble(id = nodes_df$id, new_id = nodes_df$new_id))
links_df %>%
mutate(new_from = recode(from, !!!swap),
new_to = recode(to, !!!swap))
# from to new_from new_to
# 1 3 1 1 0
# 2 3 5 1 2
# 3 5 6 2 3
# 4 6 8 3 4
# 5 8 10 4 5
# 6 10 3 5 1
从技术上讲,networkD3
希望links
数据帧中的值是它们在nodes
数据帧中引用的节点的(基于零的(索引。因此nodes
数据帧中的第一行/节点为0,依此类推。
可以使用match()
来确定目标向量中向量中每个元素的基于1的索引,并减去1得到基于0的索引。
links_df$from
#> [1] 3 3 5 6 8 10
nodes_df$id
#> [1] 1 3 5 6 8 10
match(links_df$from, nodes_df$id) - 1
#> [1] 1 1 2 3 4 5
links_df$to
#> [1] 1 5 6 8 10 3
nodes_df$id
#> [1] 1 3 5 6 8 10
match(links_df$to, nodes_df$id) - 1
#> [1] 0 2 3 4 5 1
由reprex软件包(v1.0.0(于2021-03-28创建