我有一个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。
有人可以帮我找到一个好的,快速的解决方案吗? 谢谢!
答案 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)