You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:09:59