代码之家  ›  专栏  ›  技术社区  ›  J. Doe

找到反向边,并从其oposite中减去其权重

  •  3
  • J. Doe  · 技术社区  · 7 年前

    我有一个像下面的矩阵

    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 回复  |  直到 7 年前
        1
  •  2
  •   Prem    7 年前

    使用 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")
    
        2
  •  1
  •   Mankind_2000    7 年前

    将有向弧转换为公共边对 识别反弧对 .

    步骤1: 排序弧以查找边/反弧对:

    edge <- as.data.frame( t( apply(m[c("to","from")], 1, sort)))
    names(edge) <- c("edge_to" , "edge_from")
    

    第二步: 综合和总结得出权重的绝对差异。

    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
    
        3
  •  1
  •   nghauran    7 年前

    这是另一个基于您的数据的选项

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