使用矩阵数据填充数据框

时间:2018-03-24 21:03:58

标签: r dataframe matrix igraph

我有一个大的对称矩阵,里面装有权重:

          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 个答案:

答案 0 :(得分:1)

矩阵持有权重:

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

答案 1 :(得分:0)

如果我们将矩阵转换为数据框,我相信我们可以做类似的事情:

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格式化为长格式。这会创建变量fromweight_index
  2. 然后我们按from分组(即ATBECHCZ)。
  3. 创建引导weight的{​​{1}} var并回收值,将weight_index值(由组NA生成)替换为lead的第一个weight_index值每个小组。
  4. filterweight_index == 0
  5. ungroup
  6. 创建引导to的{​​{1}} var并循环使用值,将from值替换为第一个NA值(即给出var {{1}的第4行} value from)。
  7. to我们想要的列以及所需的顺序。
  8. 数据:

    AT

答案 2 :(得分:0)

也许以下会做你想要的。请注意最后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