r - 不寻常的(对我而言)数据结构:计算两列相互指向彼此的频率
问题描述
我正在使用具有我以前从未使用过的结构的数据集。它具有这种格式(最后输入数据的代码):
df
#> Instance Alice_prefers Bob_prefers Charlie_prefers
#> 1 1 Bob Charlie Alice
#> 2 2 Bob Alice Bob
#> 3 3 Bob Charlie Bob
我正在尝试创建一个变量来显示两个人何时“匹配”,即当他们都喜欢彼此时,例如,如果 Alice 更喜欢 Bob,而 Bob 也更喜欢 Alice——这是一个相互匹配:Alice 和 Bob 匹配。
所以我想要的输出是:
output
#> Instance Alice_prefers Bob_prefers Charlie_prefers Match
#> 1 1 Bob Charlie Alice <NA>
#> 2 2 Bob Alice Bob AliceBob
#> 3 3 Bob Charlie Bob BobCharlie
使用case_when()
似乎可以解决问题,但是有没有比列出每个案例更简单的方法,就像我在下面开始做的那样?在我的真实数据集中,我希望有更多的人,而不仅仅是 Alice、Bob 和 Charlie。
第二个问题:
当我有更多的人时,例如。Alice、Bob、Charlie 和 Denise,该Match
列可能包含多个匹配项(例如,Alice 和 Bob 匹配,Charlie 和 Denise 匹配)-- 整洁的解决方案是什么?我是否应该为每个可能的匹配设置一个指标变量,例如 AliceBob、AliceCharlie 等,它的值为 1 或 0?
我这样做的原因是:我希望能够快速查看比赛的数量以及参加比赛的人。
#df <- df %>% mutate(Match = ifelse(Alice_prefers=="Bob" & Bob_prefers =="Alice", "AliceBob", NA))
df <- df %>% mutate(
Match = case_when(
(Alice_prefers=="Bob" & Bob_prefers=="Alice") ~ "AliceBob",
(Charlie_prefers=="Bob" & Bob_prefers=="Charlie") ~ "BobCharlie"
)
)
df
数据输入代码:
df <- data.frame(stringsAsFactors=FALSE,
Instance = c(1, 2, 3),
Alice_prefers = c("Bob", "Bob", "Bob"),
Bob_prefers = c("Charlie", "Alice", "Charlie"),
Charlie_prefers = c("Alice", "Bob", "Bob")
)
解决方案
你有一个图形问题,这通常意味着你应该使用 igraph。您正在寻找有向图中的相互边。
我使用 data.table 进行分组,但如果您愿意,也可以使用 tidyverse。
首先,您应该将数据重塑为整洁(长)格式。这也是整洁的输出格式。
names(df) <- gsub("_prefers", "", names(df), fixed = TRUE)
library(reshape2)
mdf <- melt(df, id.vars = "Instance")
# Instance variable value
#1 1 Alice Bob
#2 2 Alice Bob
#3 3 Alice Bob
#4 1 Bob Charlie
#5 2 Bob Alice
#6 3 Bob Charlie
#7 1 Charlie Alice
#8 2 Charlie Bob
#9 3 Charlie Bob
library(data.table)
setDT(mdf) #for group-by
library(igraph)
mdf[, Match := {
#turn subsets into graphs
g <- graph_from_data_frame(.SD[, .(variable, value)])
#initialize result
res <- character(.N)
#find reciproc pairs
m <- which_mutual(g)
#I'd probably just return m
#but just for fun,
#get names of reciproc pairs
res[m] <- attr(E(g)[m], "vnames")
res
}, by = Instance]
# Instance variable value Match
#1: 1 Alice Bob
#2: 2 Alice Bob Alice|Bob
#3: 3 Alice Bob
#4: 1 Bob Charlie
#5: 2 Bob Alice Bob|Alice
#6: 3 Bob Charlie Bob|Charlie
#7: 1 Charlie Alice
#8: 2 Charlie Bob
#9: 3 Charlie Bob Charlie|Bob
如果你只想要计数,那就更容易了:
mdf[, .(count = {
#turn subsets into graphs
g <- graph_from_data_frame(.SD[, .(variable, value)])
reciprocity(g) * .N
}), by = Instance]
# Instance count
#1: 1 0
#2: 2 2
#3: 3 2
推荐阅读
- javascript - 使用外部按钮处理表单的提交事件
- perl - 生成带有 Excel XLSX 附件的电子邮件
- javascript - 在 AngularJS 中动态更新数据
- javascript - 图片问题下的 HTML5/CSS Sticky Header
- android - 使用 WorkManagerTestInitHelper 阻止 WorkManager 完成工作的重试
- c - 链接错误:在 PlatformIO 中找不到 -lrdkafka 预编译动态库
- python - 修改 train_test_split 函数
- python - scipy.optimize.minimize 在小数点后更改值
- mongodb - 获取 mongodb 文档中的文档数
- node.js - 在 NodeJS 中部署和托管 PWA