Geomnet包 - 用户定义的坐标错误

时间:2017-10-26 19:36:56

标签: r ggplot2

我尝试使用geomnet包中的用户定义坐标为11个节点创建网络图。经过快速研究后,我发现可以通过将layout.alg设置为NULL并将x和y坐标传递给绘图来完成 - 但是没有指定是否应该使用坐标来实现'从'或者用于'到。我尝试了两种方法,但仍然存在错误:

Error in scale_apply(layer_data, x_vars, "train", SCALE_X, x_scales) :  

也许我是那个做错事的人而且非常明显,但说实话,我根本不知道。我非常感谢你提供任何帮助。

我的数据:

# A tibble: 11 x 4
    from    to     x     y
   <chr> <chr> <chr> <chr>
 1    z1    z3    40    30
 2    z2    z4    20    30
 3    z3    z5    15    30
 4    z4    z8    60    30
 5    z5    z9    10    50
 6    z6    z4    30    60
 7    z7    z4    50    50
 8    z8    z4    65    50
 9    z9    z5    20    80
10   z10    z8    40    90
11   z11    z7    60    70

我的代码:

p <- ggplot(data=fromto, aes(from_id = from, to_id = to, x=x,y=y)) 
p + geom_net(directed = TRUE,
               layout.alg = NULL,
               size = 6, arrowsize = 0.5,
               curvature = 0.05,
               arrowgap = 0.02,
               linewidth = 0.5)

当我使用较小的数据集时,它似乎工作得很好。

  from to  x  y
1   z1 z3 10 25
2   z2 z1 20 30
3   z3 z2 40 30

p <- ggplot(data=fromto, aes(from_id = from, to_id = to, x=x,y=y)) 

p + geom_net(directed = TRUE,
           layout.alg = NULL,
           size = 6, arrowsize = 0.5,
           curvature = 0.05,
           arrowgap = 0.02,
           linewidth = 0.5)

Outcome - simple plot

1 个答案:

答案 0 :(得分:4)

在对geom_net代码进行准确分析后,我发现了解geomnet:::StatNet$compute_network的工作原理是解决问题的基础。

输入

geomnet:::StatNet$compute_network(data=fromto, layout.alg =NULL)

给出(错误的)输出:

# A tibble: 21 x 7
# Groups:   from, to [21]
     from     to     x     y  xend  yend weight
   <fctr> <fctr> <int> <int> <int> <int>  <int>
 1     z1     z3    NA    NA    NA    NA      1
 2     z1     z5    40    30    10    50      1
 3    z10     z6    40    90    30    60      1
 4    z10     z8    NA    NA    NA    NA      1
 5    z11     z7    60    70    50    50      1
 6     z2    z10    20    30    40    90      1
 7     z2     z4    NA    NA    NA    NA      1
 8     z3     z5    NA    NA    NA    NA      1
 9     z3     z9    15    30    20    80      1
10     z4     z6    60    30    30    60      1
# ... with 11 more rows

geomnet:::StatNet$compute_network内部,重要的一步是构建edgelist矩阵:

net <- network::as.network(na.omit(fromto[, 1:2]), matrix.type = "edgelist")
summary(net)
( edgelist <- sna::as.edgelist.sna(net) )

输出结果为:

### summary(net)
Network adjacency matrix:
    z1 z10 z11 z2 z3 z4 z5 z6 z7 z8 z9
z1   0   0   0  0  1  0  0  0  0  0  0
z10  0   0   0  0  0  0  0  0  0  1  0
z11  0   0   0  0  0  0  0  0  1  0  0
z2   0   0   0  0  0  1  0  0  0  0  0
z3   0   0   0  0  0  0  1  0  0  0  0
z4   0   0   0  0  0  0  0  0  0  1  0
z5   0   0   0  0  0  0  0  0  0  0  1
z6   0   0   0  0  0  1  0  0  0  0  0
z7   0   0   0  0  0  1  0  0  0  0  0
z8   0   0   0  0  0  1  0  0  0  0  0
z9   0   0   0  0  0  0  1  0  0  0  0

### edgelist
      [,1] [,2] [,3]
 [1,]    1    5    1
 [2,]    4    6    1
 [3,]    5    7    1
 [4,]    6   10    1
 [5,]    7   11    1
 [6,]    8    6    1
 [7,]    9    6    1
 [8,]   10    6    1
 [9,]   11    7    1
[10,]    2   10    1
[11,]    3    9    1
attr(,"n")
[1] 11
attr(,"vnames")
 [1] "z1"  "z10" "z11" "z2"  "z3"  "z4"  "z5"  "z6"  "z7"  "z8"  "z9" 

在邻接矩阵的第一行,我们可以看到z1z3正确连接但是 行列标签已按字符值排序,未考虑该值  标签包含嵌入的数字(在我们看来)应该按数字排序。

sna::as.edgelist.sna函数依赖于行列位置而不依赖于它们的标签,因此在输出的第一行中它提供[1,] 1 5 1。这显然是错误的。

这些注意事项提出了一个可能的解决方案:避免使用嵌入数字的顶点标签,并仅使用(例如)字母表中的字母:

fromto$from_id <- LETTERS[as.numeric(gsub("z","",as.character(fromto$from_id)))]
fromto$to_id <- LETTERS[as.numeric(gsub("z","",as.character(fromto$to_id)))]
fromto

#    from_id to_id  x  y
# 1        A     C 40 30
# 2        B     D 20 30
# 3        C     E 15 30
# 4        D     H 60 30
# 5        E     I 10 50
# 6        F     D 30 60
# 7        G     D 50 50
# 8        H     D 65 50
# 9        I     E 20 80
# 10       J     H 40 90
# 11       K     G 60 70

library(geomnet)
ggplot(data=fromto, aes(from_id=from_id, to_id=to_id)) +
  geom_net(aes(x=x, y=y),layout.alg = NULL)+
  geom_text(aes(x=x, y=y, label=from_id), hjust=-1) 

enter image description here