代码之家  ›  专栏  ›  技术社区  ›  Anastasia

使用矩阵数据填充数据框

  •  1
  • Anastasia  · 技术社区  · 6 年前

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

              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)

    3 回复  |  直到 6 年前
        1
  •  1
  •   Cybernetic    6 年前

    矩阵 保持重量:

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

    enter image description here

    作用 要将权重矩阵转换为权重帧,请执行以下操作:

    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)
    

    后果 :

    enter image description here

        2
  •  0
  •   Rui Barradas    6 年前

    也许下面的内容可以满足您的需要。请注意 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
  •  0
  •   tyluRp    6 年前

    如果我们将矩阵转换为数据帧,我相信我们可以执行以下操作:

    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. 然后我们分组 从…起 (即。 AT , BE , CH , CZ ).
    3. 创造 weight 导致的var weight\u索引 并回收值,替换 NA 值(由组生成 lead )与第一个 weight\u索引 每组的值。
    4. filter 行,其中 weight_index == 0 .
    5. ungroup
    6. 创造 to 导致的var 从…起 并回收这些值,替换 不适用 第一个的值 从…起 值(即给出var的第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)