首页 > 解决方案 > 在 R/dplyr 中的行之间动态更新变量

问题描述

我有来自多个游戏战舰游戏的数据。它看起来像这样:

> data.frame(game=c(1,1,1,1,2,2,2,2),
  position=c(2,4,3,1,1,2,3,4),
  hit=c(0,0,1,0,1,0,0,0))

  game position hit
1    1        2   0
2    1        4   0
3    1        3   1
4    1        1   0
5    2        1   1
6    2        2   0
7    2        3   0
8    2        4   0

每一行是玩家的一个动作:位置是平方数,命中表示他们是否击中船。我想创建一个额外的行来指示每次移动之前的棋盘状态。它应该看起来像这样:

  game position hit board_state
1    1        2   0 [NA,NA,NA,NA]
2    1        4   0 [NA,0,NA,NA]
3    1        3   1 [NA,0,NA,0]
4    1        1   0 [NA,0,1,0]
5    2        1   1 [NA,NA,NA,NA]
6    2        2   0 [1,NA,NA,NA]
7    2        3   0 [1,0,NA,NA]
8    2        4   0 [1,0,0,NA]

因此,棋盘状态会根据最后一步的位置和结果进行更新。

我在这里发现的挑战是,board_state在第 r 行上的定义取决于它在第 r-1 行上的状态,而滞后在这里没有用,因为它在同一列中。我希望这很清楚。

关于如何实现这一点的任何想法?谢谢!!!

标签: rdplyrdynamiclag

解决方案


这是一种使用dplyrand的方法tidyr。首先,我添加一个列来跟踪我们在每场比赛中的哪个回合。(这将有助于我们在后面的步骤中进行广泛的旋转。)然后我“完成”表格以在每场比赛中的每个位置和每个回合都有一行。然后我们可以向下“填充”并后退一步,以便每个位置都反映其过去的历史。最后,我们可以按游戏和回合分组并生成一个“board_position”摘要,该摘要将每个位置的“命中”值连接起来。

library(dplyr); library(tidyr)
df %>%
  group_by(game) %>%
  mutate(turn = row_number()) %>%
  complete(game, position, turn) %>%
  group_by(game, position) %>%
  fill(hit) %>%
  mutate(hit = lag(hit)) %>%
  group_by(game, turn) %>%
  summarize(board_state = paste(hit, collapse = ", "), .groups = "drop")

结果

# A tibble: 8 × 3
   game  turn board_state   
  <dbl> <int> <chr>         
1     1     1 NA, NA, NA, NA
2     1     2 NA, 0, NA, NA 
3     1     3 NA, 0, NA, 0  
4     1     4 NA, 0, 1, 0   
5     2     1 NA, NA, NA, NA
6     2     2 1, NA, NA, NA 
7     2     3 1, 0, NA, NA  
8     2     4 1, 0, 0, NA  

推荐阅读