在R中的表中查找对

时间:2016-02-08 11:10:24

标签: r

我需要在R中的表中识别数字对。表的结构如下:

   user_A   user_B   counter
1       1        2         5
2       1        3         3
3       2        1        10
4       2        4         8

我想检查每对是否存在相反的对,例如对(1,2)和对(2,1),如果是 - 对两个对的计数器值求和。 因此,我希望以这样的表格形式输出:

   user_A   user_B   sum   bi_directional
1       1        2    15             TRUE
2       1        3     3            FALSE
3       2        4     8            FALSE

提前谢谢!

2 个答案:

答案 0 :(得分:1)

我们可以sort前两列用apply(MARGIN = 1),cbind和第三列('d1'),获得重复的索引前两列('i1')。转换为'data.table'(setDT(d2)),按'user_A'和'user_B'分组,获取'Counter'的sum和'i1'的第一行。

 d1 <- setNames(cbind(t(apply(df[1:2], 1, sort)), df[3]), names(df))
  i1 <- duplicated(d1[1:2])|duplicated(d1[1:2], fromLast=TRUE)

 d2 <- cbind(d1, i1)
 library(data.table)
 setDT(d2)[, list(counter=sum(counter), bi_directional=i1[1L]) ,.(user_A, user_B)]
 #  user_A user_B counter bi_directional
 #1:      1      2      15           TRUE
 #2:      1      3       3          FALSE
 #3:      2      4       8          FALSE

或另一种选择是

setDT(df)[user_A > user_B, c('user_B', 'user_A') := 
       list(user_A, user_B)]
df[, list(counter= sum(counter), bi_directional= .N>1), 
                                   by = .(user_A, user_B)]
#     user_A user_B counter bi_directional
#1:      1      2      15           TRUE
#2:      1      3       3          FALSE
#3:      2      4       8          FALSE

答案 1 :(得分:0)

这是一个dplyr解决方案:

df %>%
  mutate(user_A2 = pmin(user_A, user_B),
         user_B = pmax(user_A, user_B),
         user_A = user_A2) %>%
  select(-user_A2) %>%
  group_by(user_A, user_B) %>%
  summarise(sum = sum(counter), bi_directional = n() > 1) %>%
  as.data.frame
##   user_A user_B sum bi_directional
## 1      1      2  15           TRUE
## 2      1      3   3          FALSE
## 3      2      4   8          FALSE

mutate()用于重新定义user_Auser_B,以使两个值中较小的值始终位于第一列中。然后删除辅助列user_A2。数据按user_Auser_B分组,并为每个组计算两个摘要:counter之和以及是否有多个值。后者使用n()来计算组中的行数。

最后一行使用as.data.frame转换回数据框。只有在您坚持使用数据框作为结果时才需要这样做。