【问题标题】:New variable based on first appearance of another variable in each group in R基于 R 中每个组中另一个变量的首次出现的新变量
【发布时间】:2018-12-03 03:30:50
【问题描述】:

我有一个像这样的长数据框:

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

我想为 每个 玩家创建一个新变量,该变量基于 decs==3 变量的首次外观和世界状态。

也就是说,如果“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

任何想法如何做到这一点?

【问题讨论】:

  • 我不确定我是否理解您的预期输出; player_type 似乎只是players + 5,不管任何““decs”的第一次出现,不是吗?

标签: r datatable data-manipulation


【解决方案1】:

这种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

这个想法是filter你的数据用于观察decs == 3,提取每个“玩家”的第一个元素,添加player_type服从“世界”的状态,最后与你的原始数据合并。

【讨论】:

  • @YefR 很高兴它成功了。如果他们解决了您的问题,请考虑接受任何答案。问候
【解决方案2】:

一个选项是使用cumsum(decs==3) == 1 为玩家查找decs == 3 的第一次出现。现在,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  

【讨论】:

    【解决方案3】:

    我们可以使用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
    

    【讨论】:

      猜你喜欢
      • 2020-03-24
      • 2019-11-03
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多