R:分组2列,但仅当第2列不匹配时

时间:2018-06-07 20:07:30

标签: r group-by dplyr

我是R(和dplyr)的新手,我目前正在处理一些季节性足球数据,需要一些帮助。目前,如果玩家转移到同一联盟中的另一个俱乐部,那么数据行和所有指标都会被复制,但会有一个新的team_id。但是,如果玩家转移到另一个联盟,则指标会被拆分。

为了保持一致性,我需要解决这个问题,这意味着我必须:

  

由player_id分组,其中comp_id不匹配

(足球法规要求你在一个赛季中最多只能参加2个俱乐部,这样可以抵消进一步的复杂化,所以这个简单的规则可以解决所有问题)

所以换句话说,如果有重复数,则对所有行求和,但仅当comp_id不同时

我试图在dplyr中这样做,并希望有一些写这样的方式,如:

football_data %>%
group_by(player_id, !comp_id)

但这不起作用,而且非常正确。

我的另一个选择是基于复合键(player_id,comp_id)和group_by player_id创建一个额外的列,只有复合键的数量= 1,但即使这样,我也很难用dplyr写这个。

非常欢迎任何建议。

编辑:

有近百个指标,所以我将简化如下:

player_id   player_name   comp,   team,  metric1, metric2, metric3 .....
1            Lacazette     Bund   Dort     20       30       20
1            Lacazette     EPL    Ars      10       15       15
2            Arnautovic    EPL    Stoke    30       40       30     
2            Arnautovic    EPL    W. Ham   30       40       30       

所以在这个例子中,当玩家移动联盟(Lacazette)时,数据指标会被分割,但如果转移属于同一联盟(Arnautovic)则不会。

因此,为了保持一致性,我需要总结第一个玩家的指标,而不是第二个玩家的指标

产生一个输出:

player_id   player_name   comp,   team,  metric1, metric2, metric3 .....
1            Lacazette     Bund   Dort     30       45       35
1            Lacazette     EPL    Ars      30       45       35
2            Arnautovic    EPL    Stoke    30       40       30     
2            Arnautovic    EPL    W. Ham   30       40       30     

1 个答案:

答案 0 :(得分:0)

基本上,你想要

  1. 获取sum变量的玩家等级metric,按comp分组
  2. join他们回到完整的数据框架。

  3. library(tidyverse)
    #> -- Attaching packages ----------------------------------------------------------------------------------------------------- tidyverse 1.2.1 --
    #> v ggplot2 2.2.1     v purrr   0.2.4
    #> v tibble  1.4.1     v dplyr   0.7.4
    #> v tidyr   0.7.2     v stringr 1.2.0
    #> v readr   1.1.1     v forcats 0.2.0
    #> -- Conflicts -------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
    #> x dplyr::filter() masks stats::filter()
    #> x dplyr::lag()    masks stats::lag()
    
    df <- data.frame(player_id = c(1, 1, 2, 2), 
                     player_name = c("Lacazette", "Lacazette", "Arnuatovic", "Arnuatovic"), 
                     comp = c("Bund", "EPL", "EPL", "EPL"), 
                     team = c("Dort", "Ars", "Stoke", "W. Ham"), 
                     metric1 = c(20, 10, 30, 30), 
                     metric2 = c(30, 15, 40, 40), 
                     metric3 = c(20, 15, 30, 30))
    
    df %>% 
      distinct(player_id, player_name, comp, .keep_all = T) %>% 
      group_by(player_id) %>% 
      summarize_at(vars(metric1:metric3), funs(sum)) %>% 
      left_join(df %>% select(player_id:team), ., by = "player_id")
    
    
    #>   player_id player_name comp   team metric1 metric2 metric3
    #> 1         1   Lacazette Bund   Dort      30      45      35
    #> 2         1   Lacazette  EPL    Ars      30      45      35
    #> 3         2  Arnuatovic  EPL  Stoke      30      40      30
    #> 4         2  Arnuatovic  EPL W. Ham      30      40      30