R语言 根据应用于两条边的条件创建二分投影

m1m5dgzv  于 2023-11-14  发布在  其他
关注(0)|答案(1)|浏览(114)

我有一个数据集,它有不同的源节点和目标节点,还有一个与关系相关的数值变量。
它看起来有点像这样:

library(igraph)
library(tidygraph)

set.seed(24601)

example_data <- 
  data.frame(source = 
             sample(letters[1:10],
                    100,
                    replace = TRUE),
           target =
             sample(letters[16:25],
                    100,
                    replace = TRUE),
           important_variable =
             rnorm(100))

字符串
假设source的成员是个人,target的成员是他们去过的不同城市,我想创建一个网络,显示同一个人何时访问了两个给定的城市。我会使用bipartite_projection(),如下所示:

example_data %>% 
  graph_from_data_frame() %>% 
  as_tbl_graph() %>% 
  mutate(type = 
           ifelse(name %in% letters[1:10],
                   TRUE,
                   FALSE)) %>% 
  bipartite_projection(which = "true")


然而,我只想在满足一定条件的情况下连接不同的城市:例如,当important_variable的值之间的差异最大为0.5时(例如,当同一个人在同一年访问过两个城市时,我感兴趣)。目前,使用bipartite_projection后,来自important_variable的信息被丢弃。
我看不出有什么方法可以限制基于第三个数字变量的bipartite_projection。有可能吗?提前感谢您的帮助。

使用edit更新以显示所需的输出:

让我们看一小部分的行:

example_data %>% 
  filter(source == "a") %>% 
  head()

这将产生以下结果:

source target important_variable
1      a      x         0.29773720
2      a      p         1.50474490
3      a      y         0.01149263
4      a      q         0.19391773
5      a      t        -0.10656946
6      a      w        -0.29516668

我可以直接进入二分投影,像这样:

example_data %>% 
  filter(source == "a") %>% 
  head()  %>% 
  graph_from_data_frame() %>% 
  as_tbl_graph() %>% 
  mutate(type = 
           ifelse(name %in% letters[1:10],
                  TRUE,
                  FALSE)) %>% 
  bipartite_projection(which = "false")

其产生具有一个顶点属性name和一个边属性node的iGraph对象。
然而,我想要看起来像这样的东西(为了简单起见,只有前四行):

source_projected target_projected source_att  target_att
1                x                p  0.2977372  1.50474490
2                x                y  0.2977372  0.01149263
3                x                q  0.2977372  0.19391773
4                x                t  0.2977372 -0.10656946

因为这将允许我根据source_atttarget_att列之间的关系进行过滤(例如,过滤source_atttarget_att之间的差异小于0.5)

第二次更新,更详细的期望输出

@ JumasIsCoding提供了一个符合我要求的解决方案。这让我意识到我没有足够详细。
再次从原始数据开始,我们可以看到a链接到p两次,a链接到y两次。在每种情况下,important_variable的值都是不同的。如下所示:

example_data %>% 
  filter(source == "a" &
           (target == "p" |
              target == "y")) 

  source target important_variable
1      a      p         1.50474490
2      a      y         0.01149263
3      a      y        -2.34069094
4      a      p         0.29294049

我发布的示例所需数据仅包括target中的每个节点连接一次。然而,由于important_variable的值不同,我希望输出包括这些配对的所有配置,如下所示:

source_projected target_projected source_att  target_att
1                p                y  0.2977372  0.01149263
2                p                y  0.2977372 -2.34069094
3                p                y  0.2929405  0.01149263
4                p                y  0.2929405 -2.34069094

这是一个可以构建的东西吗?谢谢!

3pmvbmvn

3pmvbmvn1#

更新

由于单个目标可能有多个值,我想最好使用left_join并为relationship参数启用"many-to-many"

out <- example_data %>%
    graph_from_data_frame() %>%
    set_vertex_attr(
        name = "type",
        value = names(V(.)) %in% example_data$target
    ) %>%
    bipartite_projection() %>%
    pluck("proj2") %>%
    as_data_frame() %>%
    select(-weight) %>%
    left_join(select(example_data, -source),
        join_by(from == target),
        relationship = "many-to-many"
    ) %>%
    left_join(select(example_data, -source),
        join_by(to == target),
        relationship = "many-to-many"
    ) %>%
    rename(all_of(c(source_att = "important_variable.x", target_att = "important_variable.y")))

字符串
你会看到

> head(out)
  from to source_att  target_att
1    x  y  0.2977372  0.50506407
2    x  y  0.2977372 -1.37333412
3    x  y  0.2977372  0.61981223
4    x  y  0.2977372  0.43724194
5    x  y  0.2977372 -1.97363488
6    x  y  0.2977372 -0.02413137

> glimpse(out)
Rows: 4,462
Columns: 4
$ from       <chr> "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",…
$ to         <chr> "y", "y", "y", "y", "y", "y", "y", "y", "y", "y", "y", "y",…
$ source_att <dbl> 0.2977372, 0.2977372, 0.2977372, 0.2977372, 0.2977372, 0.29…
$ target_att <dbl> 0.50506407, -1.37333412, 0.61981223, 0.43724194, -1.9736348…

上一页

也许你可以试试下面的代码

example_data %>%
    graph_from_data_frame() %>%
    set_vertex_attr(
        name = "type",
        value = names(V(.)) %in% example_data$target
    ) %>%
    bipartite_projection() %>%
    pluck("proj2") %>%
    as_data_frame() %>%
    select(-weight) %>%
    mutate(
        source_att = with(example_data, important_variable[match(from, target)]),
        target_att = with(example_data, important_variable[match(to, target)])
    )

这给

from to  source_att  target_att
1     x  y  0.29773720  0.50506407
2     x  p  0.29773720 -0.74022203
3     x  u  0.29773720 -2.04969760
4     x  q  0.29773720  1.36281039
5     x  w  0.29773720 -0.47578690
6     x  s  0.29773720  0.03233063
7     x  t  0.29773720 -1.08378137
8     x  r  0.29773720 -0.72029435
9     x  v  0.29773720 -0.22919308
10    y  p  0.50506407 -0.74022203
11    y  u  0.50506407 -2.04969760
12    y  q  0.50506407  1.36281039
13    y  w  0.50506407 -0.47578690
14    y  s  0.50506407  0.03233063
15    y  t  0.50506407 -1.08378137
16    y  r  0.50506407 -0.72029435
17    y  v  0.50506407 -0.22919308
18    p  u -0.74022203 -2.04969760
19    p  q -0.74022203  1.36281039
20    p  w -0.74022203 -0.47578690
21    p  s -0.74022203  0.03233063
22    p  t -0.74022203 -1.08378137
23    p  r -0.74022203 -0.72029435
24    p  v -0.74022203 -0.22919308
25    r  u -0.72029435 -2.04969760
26    r  q -0.72029435  1.36281039
27    r  w -0.72029435 -0.47578690
28    r  s -0.72029435  0.03233063
29    r  t -0.72029435 -1.08378137
30    r  v -0.72029435 -0.22919308
31    u  q -2.04969760  1.36281039
32    u  w -2.04969760 -0.47578690
33    u  s -2.04969760  0.03233063
34    u  t -2.04969760 -1.08378137
35    u  v -2.04969760 -0.22919308
36    v  s -0.22919308  0.03233063
37    v  t -0.22919308 -1.08378137
38    v  q -0.22919308  1.36281039
39    v  w -0.22919308 -0.47578690
40    q  w  1.36281039 -0.47578690
41    q  s  1.36281039  0.03233063
42    q  t  1.36281039 -1.08378137
43    w  s -0.47578690  0.03233063
44    w  t -0.47578690 -1.08378137
45    s  t  0.03233063 -1.08378137

然后我猜你知道如何过滤行,并限制source_atttarget_att之间的差异。

相关问题