我的矩阵如下图所示
m <- expand.grid(LETTERS[1:24],LETTERS[1:24])
m$weight <- runif(nrow(m), 0.01, max = 1)
m <- m[m$Var1!=m$Var2, ] ##remove loop edges
colnames(m) = c("to","from","weight")
并以此形式描述有向图。我要做的是减去并取每对反边的绝对值,并创建一个描述新的无向图的新矩阵。即:
abs( edge_weight(A,B) - edge_weight(B,A) )
但是我不知道如何只考虑每对一次。
答案 0 :(得分:2)
使用igraph
library(igraph)
#dataframe to directed graph
directed_graph <- graph.data.frame(m, directed = T)
#convert to undirected graph by applying desired function
undirected_graph <- as.undirected(directed_graph, mode = "collapse",
edge.attr.comb = list(weight = function(x) abs(x[1] - x[2])))
#final result
df <- as.data.frame(cbind(get.edgelist(undirected_graph),
unlist(get.edge.attribute(undirected_graph))))
colnames(df) <- c("edge1", "edge2", "weight")
rownames(df) <- NULL
给出
> head(df)
edge1 edge2 weight
1 B C 0.310624073725194
2 B D 0.587582074650563
3 C D 0.0327853348944336
4 B E 0.19360910307616
5 C E 0.328824346032925
6 D E 0.13037203295622
示例数据
set.seed(123)
m <- expand.grid(LETTERS[1:24], LETTERS[1:24])
m$weight <- runif(nrow(m), 0.01, max = 1)
m <- m[m$Var1 != m$Var2, ]
colnames(m) <- c("to", "from", "weight")
答案 1 :(得分:1)
将有向弧转换为公共边对 以标识反向弧对。
>第1步: :对弧进行排序以找到边/反弧对:
edge <- as.data.frame( t( apply(m[c("to","from")], 1, sort)))
names(edge) <- c("edge_to" , "edge_from")
第2步: 组合并汇总,以得出权重的绝对差。
new_m <- cbind(m, edge)
library(dplyr)
new_m %>%
group_by(edge_to, edge_from) %>%
summarise(new_weight = abs(weight[1] - weight[2]))
# edge_to edge_from new_weight
# <fct> <fct> <dbl>
# 1 A B 0.0477
# 2 A C 0.0133
# 3 A D 0.162
# 4 A E 0.690
# 5 A F 0.00987
# 6 A G 0.190
# 7 A H 0.0166
# 8 A I 0.297
# 9 A J 0.226
#10 A K 0.0193
# ... with 266 more rows
答案 2 :(得分:1)
这是基于您的数据的另一种选择
library(tidyverse)
## data
m <- expand.grid(LETTERS[1:24],LETTERS[1:24],
stringsAsFactors = FALSE) # you should use stringsAsFactors = FALSE
m$weight <- runif(nrow(m), 0.01, max = 1)
#m <- m[m$Var1 != m$Var2, ] ##remove loop edges
m <- filter(m, Var1 != Var2) # filter also does the job
colnames(m) = c("to","from","weight")
## result
m <- m %>%
arrange(to) %>%
mutate(edge = ifelse(to < from, paste(to, from, sep = ","),
paste(from, to, sep = ","))) %>%
group_by(edge) %>%
mutate(final_weight = abs(weight[1] - weight[2])) %>%
select(edge, final_weight) %>%
distinct() %>%
separate(edge, c("to", "from"), ",")