在R语言中从数据框生成邻接矩阵列表
问题描述
我有如下R数据框:
df <- as.data.frame(matrix(runif(n=45, min=1, max=10), nrow=5)) colnames(df) <- c("CT1|CT1", "CT1|CT2", "CT1|CT3", "CT2|CT1", "CT2|CT2", "CT2|CT3", "CT3|CT1", "CT3|CT2", "CT3|CT3") rownames(df) <- c("A", "B", "C", "D", "E")
数据框的列名由|分隔的源名称和目标名称组成,具体数据如下:
CT1|CT1 CT1|CT2 CT1|CT3 CT2|CT1 CT2|CT2 CT2|CT3 CT3|CT1 CT3|CT2 CT3|CT3 A 1.556076 7.928573 7.997007 3.404986 4.063141 8.446360 4.701470 5.767476 7.234584 B 2.853771 5.479293 9.412347 4.475027 5.338721 7.016201 8.388517 8.104206 5.298577 C 2.589011 7.458567 2.909283 1.120513 6.396092 8.148159 6.823542 1.209981 8.750885 D 7.183206 9.927155 6.865064 4.441492 5.441872 1.971493 8.046395 5.295071 4.942874 E 4.456933 4.420317 2.129996 8.827218 2.675958 7.513399 5.977327 7.590824 3.203175
需要为数据框的每一行创建一个邻接矩阵列表,例如行A对应的邻接矩阵如下:
CT1 CT2 CT3 CT1 1.556076 7.928573 7.997007 CT2 3.404986 4.063141 8.446360 CT3 4.701470 5.767476 7.234584
解决方案
方法1:基础循环法
先提取唯一节点名称,再逐行将数据重塑为邻接矩阵:
# 提取所有唯一节点 nodes <- unique(unlist(strsplit(colnames(df), "\\|"))) node_count <- length(nodes) # 初始化存储邻接矩阵的列表 adj_matrix_list <- vector("list", nrow(df)) names(adj_matrix_list) <- rownames(df) # 逐行生成邻接矩阵 for (row_idx in seq_len(nrow(df))) { adj_matrix <- matrix( data = df[row_idx, ], nrow = node_count, byrow = TRUE, dimnames = list(nodes, nodes) ) adj_matrix_list[[row_idx]] <- adj_matrix }
验证行A的结果:
adj_matrix_list[["A"]]
输出与预期一致。
方法2:tidyverse管道式处理
适合习惯tidyverse语法的场景,通过长表宽表转换实现:
library(tidyverse) adj_matrix_list <- df %>% rownames_to_column("row_id") %>% pivot_longer(-row_id, names_to = "edge", values_to = "weight") %>% separate(edge, into = c("source", "target"), sep = "\\|") %>% group_split(row_id) %>% map(function(row_data) { row_data %>% pivot_wider(names_from = target, values_from = weight) %>% column_to_rownames("source") %>% as.matrix() }) %>% set_names(rownames(df))
方法3:按源节点分组列快速转换
如果列名是按源节点顺序排列的(如CT1开头的列连续排列),可以直接按源分组列后重塑:
# 按源节点分组列 source_col_groups <- split(colnames(df), sapply(strsplit(colnames(df), "\\|"), `[`, 1)) adj_matrix_list <- lapply(seq_len(nrow(df)), function(row_idx) { do.call(rbind, lapply(source_col_groups, function(cols) df[row_idx, cols])) }) names(adj_matrix_list) <- rownames(df)
内容的提问来源于stack exchange,提问作者Yulia Kentieva
相关产品推荐
相关产品推荐

