R dataframe - 使用一列中的公共值来查找另一列中的值

时间:2016-08-11 19:41:15

标签: r

抱歉,我无法想出一个更好的名称,我正在努力解释手头的问题,所以让我用数据框来展示一个例子。

dput(DF)

structure(list(game_id = c(162044, 162044, 162044, 162044, 162044, 
162044, 162044, 162044, 162044, 162044, 162044, 162044, 162044, 
162044, 162044, 166807, 166807, 166807, 166807, 166807, 166807, 
166807, 166807, 166807, 166807, 166807, 166807, 166807, 166807, 
166807, 166807, 166807, 166807, 166807, 167948, 167948, 167948, 
167948, 167948, 167948, 167948, 167948, 167948, 167948, 167948, 
167948, 167948, 167948, 167948, 167948), team_id = c(108738, 
108738, 108738, 108738, 108738, 108738, 108738, 126351, 126351, 
126351, 126351, 126351, 126351, 126351, 126351, 54161, 54161, 
54161, 54161, 54161, 54161, 54161, 54161, 133418, 133418, 133418, 
133418, 133418, 133418, 133418, 133418, 133418, 54161, 54161, 
54161, 54161, 54161, 54161, 54161, 54161, 54161, 135796, 135796, 
135796, 135796, 135796, 135796, 135796, 135796, 135796)), .Names = c("game_id", 
"team_id"), row.names = c(NA, 50L), class = "data.frame")  


head(DF)

   game_id team_id
1   162044  108738
2   162044  108738
3   162044  108738
4   162044  108738
5   162044  108738
6   162044  108738
7   162044  108738
8   162044  126351
9   162044  126351
10  162044  126351
11  162044  126351
12  162044  126351
13  162044  126351
14  162044  126351
15  162044  126351
16  166807   54161
17  166807   54161
18  166807   54161
19  166807   54161
20  166807   54161
21  166807   54161
22  166807   54161
23  166807   54161
24  166807  133418
25  166807  133418
26  166807  133418
27  166807  133418
28  166807  133418
29  166807  133418
30  166807  133418
31  166807  133418
32  166807  133418
33  166807   54161
34  166807   54161
35  167948   54161
36  167948   54161
37  167948   54161
38  167948   54161
39  167948   54161
40  167948   54161
41  167948   54161
42  167948  135796
43  167948  135796
44  167948  135796
45  167948  135796
46  167948  135796
47  167948  135796
48  167948  135796
49  167948  135796
50  167948  135796

这是我正在使用的数据框架。重要的是,对于每个game_id,有两个team_id。如果它有助于解决问题,则game_ids全部排序,并且team_ids可以被分组,以便对于每个game_id,出现第一个team_id的所有实例,然后出现第二个team_id的所有实例(目前不是这种情况,如你可以在第33和34行看到。我需要创建一个名为team2_id的第三列,其中此列是与game_id对应的其他team_id。所需输出的示例如下:

head(DF)

   game_id team_id team2_id
1   162044  108738   126351
2   162044  108738   126351
3   162044  108738   126351
4   162044  108738   126351
5   162044  108738   126351
6   162044  108738   126351
7   162044  108738   126351
8   162044  126351   108738   
9   162044  126351   108738
10  162044  126351   108738
11  162044  126351   108738
12  162044  126351   108738
13  162044  126351   108738
14  162044  126351   108738
15  162044  126351   108738
16  166807   54161   133418 
17  166807   54161   133418
18  166807   54161   133418
19  166807   54161   133418
20  166807   54161   133418
21  166807   54161   133418
22  166807   54161   133418
23  166807   54161   133418
24  166807  133418    54161   
25  166807  133418    54161
26  166807  133418    54161
27  166807  133418    54161
28  166807  133418    54161
29  166807  133418    54161
30  166807  133418    54161
31  166807  133418    54161
32  166807  133418    54161
33  166807   54161   133418
34  166807   54161   133418
35  167948   54161   135796
36  167948   54161   135796
37  167948   54161   135796
38  167948   54161   135796
39  167948   54161   135796
40  167948   54161   135796
41  167948   54161   135796
42  167948  135796    54161  
43  167948  135796    54161
44  167948  135796    54161
45  167948  135796    54161
46  167948  135796    54161
47  167948  135796    54161
48  167948  135796    54161
49  167948  135796    54161
50  167948  135796    54161

乍一看,我认为我不会为这种类型的数据操作而烦恼,但遗憾的是我觉得这很难。任何帮助将不胜感激!

谢谢,

1 个答案:

答案 0 :(得分:3)

以下是使用tidyrdplyr的解决方案。

library(dplyr)
library(tidyr)
teams <- DF %>%
  group_by(game_id, team_id) %>% # For every game_id and team_id
  summarise() %>% # Create one row
  # Grouping is now for every game_id
  mutate(team_number = paste0("team", row_number(), "_id")) %>% # generate the to-be column name of this team_id
  spread(team_number, team_id) # Spread the column names to create the new columns
# Now join the team data to the original DF:
res <- DF %>%
  left_join(teams, by = "game_id")

res现在具有与DF相同的列以及另外两列,team1_idteam2_id包含第一个resp的team_id。游戏中的第二个团队,因为它出现在数据中。它还会使team_id列等于team1_idteam2_id,具体取决于实际玩家属于哪个团队。

有趣的事实:如果game_id有两个以上team_id,则代码会根据需要优雅地创建新列team3_idteam4_id等。