我需要在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
提前谢谢!
答案 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_A
和user_B
,以使两个值中较小的值始终位于第一列中。然后删除辅助列user_A2
。数据按user_A
和user_B
分组,并为每个组计算两个摘要:counter
之和以及是否有多个值。后者使用n()
来计算组中的行数。
最后一行使用as.data.frame
转换回数据框。只有在您坚持使用数据框作为结果时才需要这样做。