[英]Finding pairs in a table in 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
先感谢您!
我们可以使用apply
(MARGIN = 1)对前两列进行按行sort
,与第三列('d1') cbind
,获得前两列重复项的索引('i1')。 转换为“data.table”( setDT(d2)
通过“用户_A”和“用户_B”分组,得到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
这是一个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_A
和user_B
,以便两个值中的较小者始终位于第一列中。 然后,删除辅助列user_A2
。 数据按user_A
和user_B
分组,并为每个组计算两个摘要: counter
总和以及是否有多个值。 后者使用n()
来计算组中的行数。
最后一行使用as.data.frame
转换回数据帧。 仅当您坚持要使用数据框作为结果时才需要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.