使用dplyr计算数据列中的“条纹”

uhry853o  于 2023-05-20  发布在  其他
关注(0)|答案(2)|浏览(222)

我不认为标题清楚地解释了我需要做的数据计算,所以我创建了一个简单的可重复的例子如下:
这里是输入数据框

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

我只是尝试获得以下输出的“home streaks”:

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

输出解释-客队以2分开始比赛(第6行和第7行分别一次得1分)-2,则主队得2分(第10行)2,则客队得3分(第11行)-3,则主队得2分(第12行)2,则客队得5分(第13、16行)-5,则主队得1分(第18行)1。主场连胜是阳性,客场连胜是阴性。
优选地,这些条纹将作为单独的列被创建到称为streaks或类似的 Dataframe 上,并且 Dataframe 将被过滤(在该示例中从18到6行),对于哪些行被丢失没有真实的的偏好。
我正在积极地做这件事,但我想在这里发帖,因为我在过去的一段时间里一直在努力。任何帮助都非常感谢!

**编辑:**一个特殊的挑战是,我不能简单地在homeMargin列中查找更改,因为margin中的单个更改不等于连续。相反,条纹涉及在相同方向上的边缘的连续变化。
**Edit 2:**我的努力是沿着这些路线到目前为止:

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

......然而,这并没有真正让我去我需要去的地方......

qxsslcnc

qxsslcnc1#

这里有一个方法:

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
nlejzf6q

nlejzf6q2#

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

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

相关问题