我有一个具有以下格式的数据框:
pair group group_rank win_prob
<int> <int> <chr> <dbl>
1 1 first 0.6
1 2 second 0.4
2 3 first 0.5
2 4 second 0.5
它是用以下代码段生成的:
library(tidyverse)
df <- tibble(pair = rep(c("A", "B"), each = 2),
group = seq(1:4),
group_rank = c("first", "second", "first", "second"),
win_prob = c(0.6, 0.4, 0.5, 0.5))
我的目标是将“获胜”分配给每对中的一组,将“损失”分配给 另一组。换句话说,我想产生以下 具有新列结果的数据框:
pair group group_rank win_prob outcome
<int> <int> <chr> <dbl> <chr>
1 1 first 0.6 win
1 2 second 0.4 loss
2 3 first 0.5 loss
2 4 second 0.5 win
应将“赢”或“亏损”分配给结果变量 基于group_rank和win_prob中的相应值 变量。更具体地说,每次我想先检查是否 通过检查是否具有group_rank ==“ first”的组获胜 其win_prob> = runif(1)(伯努利径)。
如果条件满足,我想为此分配“胜利” 组。如果不满足条件,我要分配“损失”。
在确定group_rank ==“ first”的组是否具有 胜负,我想将相反的结果分配给 group_rank ==“第二”。因此,如果“第一”组已经 分配“胜利”,第二组应该分配“损失”, 反之亦然。
在伪代码中,应该是这样,但是窍门是如何在分组的数据框中查找“第一”组的结果,同时确定“第二”组的结果:
for pair in pairs:
if group_rank == ``first'' and win_prob >= runif(1):
outcome <- ``win''
else:
outcome <- ``loss''
if group_rank == ``second'':
if outcome == ``win'' for group with group_rank == ``first'':
outcome <- ``loss''
else:
outcome <- ``win''
在tidyverse框架中是否有一种简单的方法来实现这一目标?
答案 0 :(得分:2)
使用data.table
可以做到这一点:
res <- c("win", "lose") # Not a good name but this is one of two possible results.
setDT(df)[,
outcome := {
temp = win_prob[1] >= runif(1);
ifelse(c(temp, temp), res, rev(res))
},
by = pair]
df
pair group group_rank win_prob outcome
1: A 1 first 0.6 win
2: A 2 second 0.4 lose
3: B 3 first 0.5 lose
4: B 4 second 0.5 win
使用dplyr
:
df %>%
group_by(pair) %>%
mutate(temp = win_prob[1] >= runif(1)) %>%
mutate(outcome = ifelse(temp, res, rev(res))) %>%
select(-temp)
注意:
两种解决方案都假设数据已经排序,因此对于每对数据,group_rank first始终显示在上方。