[英]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.