Найдите ребро в обратном направлении и вычтите его вес из противоположного - PullRequest
0 голосов
/ 04 июля 2018

у меня матрица похожа на следующую

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) )

Но я не знаю, как учитывать только один раз каждую пару.

Ответы [ 3 ]

0 голосов
/ 04 июля 2018

Вот еще один вариант, основанный на ваших данных

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"), ",")
0 голосов
/ 04 июля 2018

Использование 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")
0 голосов
/ 04 июля 2018

Преобразование направленных дуг в общие пары ребер для идентификации обратной пары дуг .

Шаг 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...