【问题标题】:Filling a data frame using matrix data使用矩阵数据填充数据框
【发布时间】:2018-09-03 07:51:52
【问题描述】:

我有一个充满权重的大型对称矩阵:

          AT      BE     CH     CZ
AT    0       0.00276 0.148  0.109
BE    0.00276 0       0.145  0.112
CH    0.148   0.145   0      0.257
CZ    0.109   0.112   0.257  0  

我需要创建一个数据框,列出所有元素之间的链接(除了相同的元素,例如 AT 和 AT、BE 和 BE 等)和相应的权重。换句话说,我不知道如何用矩阵中的数据填充我的数据框。数据框应该看起来有点类似于

df<-data.frame(from = c("AT", "BE", "CH", "CZ"), to= c("BE", "CH", "CZ", "AT"),
weight=c(0.003,0.145,0.257,0.109))

我需要这种类型的数据框来用 igraph 进一步可视化它,这里建议Visualizing data on geographic map with networks (R)

【问题讨论】:

    标签: r dataframe matrix igraph


    【解决方案1】:

    如果我们将矩阵转换为数据框,我相信我们可以这样做:

    library(dplyr)
    library(tidyr)
    
    df %>% 
      gather(from, weight_index) %>% 
      group_by(from) %>% 
      mutate(weight = lead(weight_index, default = weight_index[1])) %>% 
      filter(weight_index == 0) %>% 
      ungroup() %>% 
      mutate(to = lead(from, default = from[1])) %>% 
      select(from, to, weight)
    
    # A tibble: 4 x 3
      from  to     weight
      <chr> <chr>   <dbl>
    1 AT    BE    0.00276
    2 BE    CH    0.145  
    3 CH    CZ    0.257  
    4 CZ    AT    0.109
    
    1. 我们将数据帧和gather 转换为长格式。这将创建变量 from 和 weight_index。
    2. 然后我们按from 分组(即AT、BE、CH、CZ)。
    3. 创建weight var,它引导weight_index 并回收这些值,将NA 值(来自lead 组)替换为每个组的第一个weight_index 值。
    4. filterweight_index == 0 所在的行。
    5. ungroup
    6. 创建to var 引导from 并回收值,将NA 值替换为第一个from 值(即给出var to 值AT 的第4 行)。
    7. select 我们想要的列并按所需的顺序。

    数据:

    Lines <- "AT      BE     CH     CZ
              AT    0       0.00276 0.148  0.109
              BE    0.00276 0       0.145  0.112
              CH    0.148   0.145   0      0.257
              CZ    0.109   0.112   0.257  0"
    
    df <- read.table(text = Lines, header = T, stringsAsFactors = F)
    

    【讨论】:

      【解决方案2】:

      也许以下内容可以满足您的要求。注意最后weight 的值的差异。

      首先是输入数据。

      mat <-
      structure(c(0, 0.00276, 0.148, 0.109, 0.00276, 0, 0.145, 0.112, 
      0.148, 0.145, 0, 0.257, 0.109, 0.112, 0.257, 0), .Dim = c(4L, 
      4L), .Dimnames = list(c("AT", "BE", "CH", "CZ"), c("AT", "BE", 
      "CH", "CZ")))
      

      现在,代码。

      mat2 <- cbind(mat[, -1], mat[, 1])
      colnames(mat2)[ncol(mat2)] <- colnames(mat)[1]
      mat2
      
      df2 <- data.frame(from = rownames(mat2), to = colnames(mat2), weight = diag(mat2))
      
      df<-data.frame(from = c("AT", "BE", "CH", "CZ"), to= c("BE", "CH", "CZ", "AT"),
      weight=c(0.003,0.145,0.257,0.109))
      
      all.equal(df, df2)
      #[1] "Component “weight”: Mean relative difference: 0.08"
      

      此“错误”是由于舍入错误造成的,例如,在您的示例输出中,您将 0.00276 舍入到 0.003。

      【讨论】:

        【解决方案3】:

        矩阵持有权重:

        mtx <- matrix( 
           c(0,0.00276,0.148,0.109,0.00276,0,0.145,0.112,0.148,0.145,0,0.257,0.109,0.112,0.257,0),  
           nrow=4, 
           ncol=4) 
        rownames(mtx) <- c('AT','BE','CH','CZ')
        colnames(mtx) <- c('AT','BE','CH','CZ')
        

        函数将权重矩阵转换为权重框架:

        mtx_to_igraph_frame <- function(mtx) {
            combs <- expand.grid(rownames(mtx), colnames(mtx))
            combs <- subset(combs, Var1 != Var2)
            combs <- t(apply(combs, 1, sort))
            combs <- combs[!duplicated(combs),]
            extract_vals <- NULL
            for(i in 1:nrow(combs)) { extract_vals[i] <- mtx[combs[i,1],combs[i,2]] }
            combs <- data.frame(combs)
            combs$weight <- extract_vals
            names(combs) <- c('from', 'to', 'weight')
            row.names(combs) <- NULL
            return(combs)
            }
        

        用法:

        mtx_to_igraph_frame(mtx)
        

        结果:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-20
          • 2014-11-21
          • 2021-10-02
          • 2014-07-28
          相关资源
          最近更新 更多