【问题标题】:Count occurence of values for every possible pair计算每个可能对的值出现次数
【发布时间】:2015-02-27 12:40:28
【问题描述】:

我有一个 ID 列表和这些 ID 所在的位置。现在我想找到最有共同点的 id 对。

我的数据框如下所示:

  id        place           
  Dave      Paris
  Dave      Moscow
  Dave      New York
  Joe       New York
  Joe       Tokyo
  Stuart    Paris
  Stuart    Moscow
  Stuart    New York
  Stuart    Tokyo

结果应如下所示:

pair1   pair2       count
Dave    Joe         1
Dave    Stuart      3
Joe     Stuart      2

我尝试过 split 来划分数据:

temp = split(df$name, df$place)

所以我现在将地点分组,但我没有进一步。

原始数据集有大约 100.000 个唯一 ID。

谁能帮我找到一个好的和快速的解决方案? 谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以试试

    library(reshape2)
    tbl <-  crossprod(table(df1[2:1]))
    tbl[upper.tri(tbl, diag=TRUE)] <- 0
    res <- subset(melt(tbl), value!=0)
    colnames(res) <- c(paste0('pair',1:2), 'count')
    row.names(res) <- NULL
    res
    #   pair1 pair2 count
    #1    Joe  Dave     1
    #2 Stuart  Dave     3
    #3 Stuart   Joe     2
    

    或者另一种选择是

    Subdf <- subset(merge(df1, df1, by.x='place',
                   by.y='place'), id.x!=id.y)
    Subdf[-1] <- t(apply(Subdf[-1], 1, sort))
    aggregate(place~., unique(Subdf), FUN=length)
    #  id.x   id.y place
    #1 Dave    Joe     1
    #2 Dave Stuart     3
    #3  Joe Stuart     2
    

    【讨论】:

    • 愚蠢的我,我不知道我可以将数据框与自身合并(这正是我在 MySQL 中所做的)。所以,你的第二个选项对我来说工作得更快,谢谢!
    • @Laura 是的,这是此类情况的一种选择
    【解决方案2】:

    或者……

    library(dplyr)
    
    df1 %>%
      left_join(df1, by = "place") %>%
      filter(id.x < id.y) %>%
      group_by(id.x, id.y) %>%
      summarise(count = n())
    

    编辑: 如果 ID 是因素运算符 &lt; 将不起作用。 Conversion 为解决方案添加了另一行(感谢 Steven Beaupré):

    df1 %>%
      left_join(df1, by = "place") %>%
      mutate_each(funs(as.character(.))) %>%
      filter(id.x < id.y) %>%
      group_by(id.x, id.y) %>%
      summarise(count = n())
    

    【讨论】:

    • 如果 ID 是字符,您可以节省几次击键并执行 left_join(df, df, by = "place") %&gt;% filter(id.x &lt; id.y) %&gt;% count(id.x, id.y)
    • 您还可以通过以下方式一次将所有内容转换为角色:mutate_each(funs(as.character(.)))。对字符使用&lt; 运算符是一个聪明的主意。 +1
    【解决方案3】:

    对于dplyr-esque 解决方案,

    你可以这样做:

    left_join(df, df, by = "place") %>%
      rename(pair1 = id.x, pair2 = id.y) %>%
      filter(!pair1 == pair2, !duplicated(t(apply(., 1, sort))) == TRUE) %>% 
      count(pair1, pair2) 
    

    【讨论】:

      猜你喜欢
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-09
      • 2012-10-25
      相关资源
      最近更新 更多