计算每个可能对的值的出现次数

时间:2015-02-26 12:44:02

标签: r

我有一个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

我尝试拆分以分割数据:

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

所以我现在把地方分组了,但我没有进一步。

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

有人可以帮我找到一个好的,快速的解决方案吗? 谢谢!

3 个答案:

答案 0 :(得分:3)

您可以尝试

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

答案 1 :(得分:3)

或......

library(dplyr)

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

修改: 如果ID是因素,则运算符<将不起作用。转换为解决方案增加了另一条线(StevenBeaupré的信用额度):

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())

答案 2 :(得分:1)

对于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)