【问题标题】:How can I create a running total for a column in a data frame but skip the first observation?如何为数据框中的列创建运行总计但跳过第一次观察?
【发布时间】:2018-12-21 14:01:30
【问题描述】:

我正在尝试在 R 中创建一个回归模型,以预测高尔夫球手下一洞的得分。一个已被证明是“接下来会发生什么”的良好指标的输入参数是前一个洞的累积分数,但我无法以编程方式添加此列。例如,在第 1 洞,玩家的累积得分为 0,玩家在第一个洞获得 5,因此第 2 洞的累积得分为 5 (0 + 5) 等等。

我已经能够使用 dplyr 成功地将一列 (cum_score) 添加到数据框中,但它并不完全符合我需要的上下文。我的代码将在第 1 洞开始“累积”,因此在这种情况下,第 1 洞的累积分数是 5,而它需要为零。本质上,我需要跳过第一次观察,然后开始运行总计。

我使用的东西

scores <- scores %>% group_by(round_id) %>% mutate(cum_score = cumsum(score))

round_id  score_id  hole_number  score  cum_score
1         100       1            4      4
1         101       2            5      9
1         102       3            4      13
1         103       4            4      17
...
2         150       1            6      6
2         151       2            4      10
...

我可以通过运行以下命令获得我想要的结果,但随后我丢失了第 1 洞的数据,并且不确定如何将 cum_score 列“插入”回数据框中

scores %>% group_by(round_id) %>% filter(hole_number > 1) %>% mutate(cum_score = cumsum(score))

我想创造什么

round_id  score_id  hole_number  score  cum_score
1         100       1            4      0
1         101       2            5      4
1         102       3            4      9
1         103       4            4      13
...
2         150       1            6      0
2         151       2            4      6
...

首先,感谢您到目前为止的回复,但到目前为止给出的答案将跳过第一行。下面是一个更好的数据示例

round_id  score_id  hole_number  score  cum_score(what i need)  what the answers output
1         100       1            4      0                        0
1         101       2            4      4                        4
1         102       3            4      8                        8
1         103       4            3      12                       11
1         104       5            4      15                       15

【问题讨论】:

  • 你可以使用lag,比如mutate(cum_score = cumsum(lag(score, default = 0)))
  • 谢谢@phiver,但这也给了我跳过第一行的问题,我确实需要它落后但不要失去第一洞的分数。

标签: r dplyr regression


【解决方案1】:

有多种方法可以做到这一点。一种方法是确保第一个条目始终为 0,然后取 cumsumscore 并忽略最后一个条目。

library(dplyr)

df %>%
  group_by(round_id) %>%
  mutate(cum_score = c(0, head(cumsum(score), -1)))


#  round_id score_id hole_number score cum_score
#     <int>    <int>       <int> <int>     <dbl>
#1        1      100           1     4         0
#2        1      101           2     5         4
#3        1      102           3     4         9
#4        1      103           4     4        13
#5        2      150           1     6         0
#6        2      151           2     4         6

数据

df <- structure(list(round_id = c(1L, 1L, 1L, 1L, 2L, 2L), score_id = 
c(100L,101L, 102L, 103L, 150L, 151L), hole_number = c(1L, 2L, 3L, 4L, 
1L, 2L), score = c(4L, 5L, 4L, 4L, 6L, 4L)), .Names = c("round_id", 
"score_id", "hole_number", "score"), row.names = c(NA, -6L), class = 
"data.frame")

【讨论】:

  • 感谢您,运行时它给我带来了与上述相同的问题...我正在测试的一个示例回合的分数为 4 4 4 3 4。我需要 cum_score 为 0 4 8 12 15。当我运行上面的代码时,它给了我 0 4 8 11 15。所以我真的需要以前分数的总和,如果这有意义的话。
  • @Dovahkiin 无法重现。当我执行score &lt;- c(4, 4, 4, 3, 4); c(0, head(cumsum(score), -1)) 时,它给了我0 4 8 12 15,这与您的预期输出相同。
  • 你是对的,这种方式确实可以按预期工作,抱歉,谢谢!
猜你喜欢
  • 2023-01-18
  • 2022-09-30
  • 2019-10-02
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
相关资源
最近更新 更多