【问题标题】:Use dplyr to compute "streaks" in column of data使用 dplyr 计算数据列中的“条纹”
【发布时间】:2019-11-02 13:51:45
【问题描述】:

我认为标题没有清楚地解释我需要做的数据计算,所以我在下面创建了一个简单的可重现示例:

这是输入数据框

structure(list(homePoints = c(0, 0, 0, 0, 0, 0, 0, 
0, 0, 2, 2, 4, 4, 4, 4, 4, 4, 5), awayPoints = c(0, 
0, 0, 0, 0, 1, 2, 2, 2, 2, 5, 5, 8, 8, 8, 10, 10, 10), homeMargin = c(0, 
0, 0, 0, 0, -1, -2, -2, -2, 0, -3, -1, -4, -4, -4, -6, -6, -5
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-18L))

# A tibble: 18 x 3
   homePoints awayPoints homeMargin
        <dbl>      <dbl>      <dbl>
 1          0          0          0
 2          0          0          0
 3          0          0          0
 4          0          0          0
 5          0          0          0
 6          0          1         -1
 7          0          2         -2
 8          0          2         -2
 9          0          2         -2
10          2          2          0
11          2          5         -3
12          4          5         -1
13          4          8         -4
14          4          8         -4
15          4          8         -4
16          4         10         -6
17          4         10         -6
18          5         10         -5

而我只是试图获得以下“主场连胜”的输出

c(-2, 2, -3, 2, -5, 1)

输出解释 - 客队以 2 分开始比赛(分别在第 6 行和第 7 行分别获得 1 分)-2,然后主队获得 2 分(第 10 行) ) 2,然后客队得 3 分(第 11 行)-3,然后主队得 2 分(第 12 行)@987654326 @,则客队得5分(第13、16行)-5,则主队得1分(第18行),1强>。主场连胜为正,客场连胜为负。

最好将这些条纹作为单独的列创建到名为 streaks 或类似名称的数据帧上,并且数据帧将被过滤(在本例中为 18 到 6 行),而对于哪些行没有真正的偏好丢失了。

我正在积极努力,但想在这里发帖,因为我在最后一段时间一直在努力解决这个问题。非常感谢任何帮助!

编辑:一个特别的挑战是我不能简单地查找 homeMargin 列中的变化,因为边距中的单个变化并不等于连续。相反,条纹涉及在同一方向上的边距连续变化。

Edit2:到目前为止,我的努力是这样的:

my_data %>%
    dplyr::mutate(streakDirection = c(0, diff(zoo::as.zoo(homeMargin), na.pad = F))) %>%
    dplyr::mutate(signChange = c(0, diff(sign(streakDirection))))

...但这并不能真正让我到达我需要去的地方...

【问题讨论】:

    标签: r dplyr data-manipulation


    【解决方案1】:

    这是一种方法:

    points %>%
      mutate(change_net = homeMargin - lag(homeMargin, default = 0),
             direction  = sign(change_net)) %>%
      filter(direction != 0) %>%
      mutate(streak = cumsum(direction != lag(direction, default = 0))) %>%
      count(streak, wt = change_net)
    
    # A tibble: 6 x 2
      streak     n
       <int> <dbl>
    1      1    -2
    2      2     2
    3      3    -3
    4      4     2
    5      5    -5
    6      6     1
    

    【讨论】:

      【解决方案2】:

      相同的想法,有点不同的实现:

      my_data %>% 
            mutate(mdif = c(0 , (diff(homePoints) - diff(awayPoints))), 
                   msgn=sign(mdif)) %>% 
            filter(mdif!=0) %>% 
            mutate(mgrp=cumsum((msgn!=lag(msgn, default = 0))))  %>%  
            group_by(mgrp)  %>% 
            summarise(mdif = sum(mdif)) %>% 
            pull(mdif)
      
      #> [1] -2  2 -3  2 -5  1
      

      【讨论】:

      • 是的,我实际上在我的代码中做了类似的事情。 group_by 后跟 mutate 后跟 filter 而不是使用 count
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多