[英]New variable based on first appearance of another variable in each group in R
I have a long data frame like this one: 我有一个像这样的长数据框:
set.seed(17)
players<-rep(1:2, c(5,5))
decs<-sample(1:3,10,replace=TRUE)
world<-sample(1:2,10,replace=TRUE)
gamematrix<-cbind(players,decs,world)
gamematrix<-data.frame(gamematrix)
gamematrix
players decs world
1 1 1 1
2 1 3 1
3 1 2 2
4 1 3 2
5 1 2 2
6 2 2 2
7 2 1 2
8 2 1 1
9 2 3 2
10 2 1 2
I want to create for each player a new variable, that is based on the first appearance of the decs==3 variable, and the state of the world. 我想为每个玩家创建一个新变量,该变量基于decs == 3变量的首次出现以及世界的状态。
That is, if when the first appearance of "decs", the state of the world was "1", then the new variable should get the value of "6", otherwise, "7", as follows: 也就是说,如果当第一次出现“ decs”时,世界的状态为“ 1”,那么新变量应获得值“ 6”,否则为“ 7”,如下所示:
players decs world player_type
1 1 1 1 6
2 1 3 1 6
3 1 2 2 6
4 1 3 2 6
5 1 2 2 6
6 2 2 2 7
7 2 1 2 7
8 2 1 1 7
9 2 3 2 7
10 2 1 2 7
Any ideas how to do it? 有什么想法怎么做?
This tidyverse
approach might be a little cumbersome but it should give you what you want. 这种tidyverse
方法可能有点麻烦,但它应该可以为您提供所需的东西。
library(tidyverse)
left_join(
gamematrix,
gamematrix %>%
filter(decs == 3) %>%
group_by(players) %>%
slice(1) %>%
mutate(player_type = ifelse(world == 1, 6, 7)) %>%
select(players, player_type),
by = 'players'
)
# players decs world player_type
#1 1 1 1 6
#2 1 3 1 6
#3 1 2 2 6
#4 1 3 2 6
#5 1 2 2 6
#6 2 2 2 7
#7 2 1 2 7
#8 2 1 1 7
#9 2 3 2 7
#10 2 1 2 7
The idea is to filter
you data for observations where decs == 3
, extract the first element per 'players', add player_type
subject to the state of the 'world' and finally merge with your original data. 我们的想法是filter
你的意见,其中数据decs == 3
,提取第一要素按“播放器”,添加player_type
受到“世界”的状态,最后用原来的数据合并。
An option is to use cumsum(decs==3) == 1
to find first occurrence of decs == 3
for a player. 一种选择是使用cumsum(decs==3) == 1
来查找玩家第一次出现的decs == 3
。 Now, dplyr::case_when
can be used to assign player type. 现在, dplyr::case_when
可用于分配播放器类型。
library(dplyr)
gamematrix %>% group_by(players) %>%
mutate(player_type = case_when(
world[first(which(cumsum(decs==3)==1))] == 1 ~ 6L,
world[first(which(cumsum(decs==3)==1))] == 2 ~ 7L,
TRUE ~ NA_integer_))
# # A tibble: 10 x 4
# # Groups: players [2]
# players decs world player_type
# <int> <int> <int> <int>
# 1 1 1 1 6
# 2 1 3 1 6
# 3 1 2 2 6
# 4 1 3 2 6
# 5 1 2 2 6
# 6 2 2 2 7
# 7 2 1 2 7
# 8 2 1 1 7
# 9 2 3 2 7
# 10 2 1 2 7
We could use data.table
我们可以使用data.table
library(data.table)
setDT(gamematrix)[, player_type := c(7, 6)[any(decs == 3& world == 1) + 1],
by = players]
gamematrix
# players decs world player_type
# 1: 1 1 1 6
# 2: 1 3 1 6
# 3: 1 2 2 6
# 4: 1 3 2 6
# 5: 1 2 2 6
# 6: 2 2 2 7
# 7: 2 1 2 7
# 8: 2 1 1 7
# 9: 2 3 2 7
#10: 2 1 2 7
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.