【问题标题】:How to create edge-list R without duplications如何创建没有重复的边缘列表 R
【发布时间】:2019-09-13 03:21:22
【问题描述】:

我有一个非常大的数据集,其中包含 3 列兴趣、id、house 和 people。每个 id 可以有多个房子,每个房子可以有多个人。我想使用@David Arenburg 在这里分享的内容创建一个边缘列表Creating edge list with additional variables in R

但是,我遇到的问题是给出的边缘是“a;b”和“b;a”。我只想拥有它们一次。由于 a 和 b 的大集合可以产生数千个 a;b, b;a 组合。

我想只拥有一次,因为我想计算人们共用一个房子的次数。

给定数据集

id=c(rep("ID1",3), rep("ID2",6), "ID3", rep("ID4",5))
house=c(rep("house1",2), "house2", rep("house3",2), rep("house4",4), "house5", rep("house6",3), "house7", "house8")
people=c("a","b","c","d","e","d","e","d","e","f","g","h","h","h","h")

df1 <- data.frame(id,house, people)

@David Arenburg 的以下代码为我们提供了边缘列表

df1 = setDT(df1)[, if(.N > 1) tstrsplit(combn(as.character(people),
              2, paste, collapse = ";"), ";"),
            .(id, house)]

结果

     id  house V1 V2
 1: ID1 house1  a  b
 2: ID2 house3  d  e
 3: ID2 house4  d  e
 4: ID2 house4  d  d
 5: ID2 house4  d  e
 6: ID2 house4  e  d
 7: ID2 house4  e  e
 8: ID2 house4  d  e
 9: ID4 house6  g  h
10: ID4 house6  g  h
11: ID4 house6  h  h

如您所见,在 V1 和 V2 之间,房子同时有 'd;e'、'e;d' 我想避免。因此,对于大量数据,这些组合可能在 1000 秒内

感谢您的帮助

【问题讨论】:

    标签: r data.table edge-list


    【解决方案1】:

    我确信有一个更简洁的基本 R 方法,但这里有一个 dplyr 方法,我们对两个值进行排序以便更容易消除重复。

    library(dplyr)
    df %>%
      mutate(V1s = if_else(V1 < V2, V1, V2),
             V2s = if_else(V1 < V2, V2, V1)) %>%
      distinct(id, house, V1s, V2s)
    

    【讨论】:

      【解决方案2】:

      @David Aremburg 提供的出色答案提供了一种可能性。

      总体策略:

      1. 使用有序边创建一个新变量(即,将“e -> d”转换为“d -> e”)
      2. 获取idhouse 和新变量的每个组合的唯一值。
      3. 删除变量

      .

      library(data.table)
      
      # keep Aremburg's solution and chain a couple of additional commands:
      setDT(df1)[, 
                 if(.N > 1) tstrsplit(combn(as.character(people),
                                            2, paste, collapse = ";"), ";"),
                  .(id, house)][, 
                               edge := apply(.SD, 
                                             1, 
                                             function(x) paste(sort(c(x[1], 
                                                                      x[2])), 
                                                               collapse = ",")), 
                               .SDcols = c("V1", "V2")][, 
                                                        .SD[1, ], 
                                                        by = .(id, house, edge)][
                                          , edge := NULL][]
      
          id  house V1 V2
      1: ID1 house1  a  b
      2: ID2 house3  d  e
      3: ID2 house4  d  e
      4: ID2 house4  d  d
      5: ID2 house4  e  e
      6: ID4 house6  g  h
      7: ID4 house6  h  h
      

      请注意,您也可以删除 V1 == V2 所在的行,因为它们是不相关的边缘。这可以在前一个链的末尾使用[V1 != V2, ] 来完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-07
        相关资源
        最近更新 更多