【问题标题】:Cumulative sum, with lag, by group, on date-stamped observations带日期标记的观测值的累积总和,按组分类
【发布时间】:2016-08-04 21:37:08
【问题描述】:

我有来自 GameDay 服务器的击球数据数据集:

  eliasID teamID                     gameID gameDate h hr bb so rbi ab runs t d lob sb cs sf hbp

1  430203    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 1 2    0 0 0   0  0  0  0   0

2  459714    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 1  0  0  1   0  3    1 0 0   1  0  0  0   0

3  325392    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 0  0  1  0   0  1    0 0 0   0  0  0  0   0

4  429801    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 0  0  0  1   0  3    0 0 0   2  0  0  0   0

5  456714    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 0  0  1  0   0  4    0 0 0   2  0  0  0   0

6  150449    kca 2010/04/01/arimlb-kcamlb-1 4/1/2010 0  0  0  1   1  4    0 0 0   2  0  0  0   0

     ba ID gameDateFormat year Year
1 0.345  1     2010-04-01 2010   NA
2 0.250  2     2010-04-01 2010   NA
3 0.319  3     2010-04-01 2010   NA
4 0.327  4     2010-04-01 2010   NA
5 0.333  5     2010-04-01 2010   NA
6 0.217  6     2010-04-01 2010   NA

我的问题是,我想为每场比赛建立一个连续的击球总数 (ab),但只计算 gameDate 低于该行的 gameDate 的游戏的总击球数,以及同一游戏年的比赛。

我查看了 for 循环并建议使用 dplyr,但是当我需要将持续的总和添加到每个游戏中以显示该玩家今年的 ab 总数时,这些都想对一个玩家的所有 ab 列求和到目前为止那场比赛。

我正在尝试构建与您在棒球参考网站上看到的那种统计数据相当的数据。

英文,我在找:

对于 Batting 中的每个 EliasID、gameID: sum(ab) 用于 EliasID,其中 gameDate

你怎么看?

【问题讨论】:

  • 欢迎来到 SO。请参阅how to make a great R reproducible example。如所写,您的问题不是很清楚或无法重现。
  • 我觉得这个问题是新用户的诚实努力,不应该立即被否决。
  • 是 sum(ab) 还是 sum(ba)?
  • @Robert 大概是 ab 是“击球率”,ba 是“击球率”,总和没有意义
  • 我无法从您建议的网页中制作可重现的示例。

标签: r for-loop sum dplyr


【解决方案1】:

欢迎来到 R 编程。因为您没有提供完整的样本数据(即dput() 而不仅仅是print(),所以这个答案做了几个假设:

  • 您的data.frame 称为df。您可以将此名称替换为实际名称。
  • 您的gameDate 是一个实际的日期向量,而不仅仅是一个字符串向量。如果是字符串,则将其更改为带有df$gameDate <- as.Date(df$gameDate, format = "%m/%d/%Y") 的日期

看来您想要的是“按组计算的“滞后的累积总和”。 (我建议你把它作为你的标题,以明确这就是你想要的。)让我们看看这两个部分。

累积和,有滞后

正如this answer 中所建议的,将滞后1 引入cumsum() 的一种简单方法是将向量x1, x2, ... xn 替换为0, x1, x2, ... xn-1。因此:

cumsumLag1 <- function(x){
  cumsum(c(0, head(x, n = -1))) # see ?cumsum and ?head, particularly the note on negative n
}
# test it out on first 5 counting numbers
cumsumLag1(1:5) # returns: 0  1  3  6 10

您的数据集应该按照累积函数的正确时间顺序排列。所以你可以用?order 做一些事情,比如:

df <- df[order(df$gameDate)]

但我们将在dplyr 中使用arrange()(见下文)以保持简单。

按组

many ways 按组进行求和(和类似功能)。也许最简单的语法是dplyr 中的%&gt;% group_by(thing)。您想按年份分组,也许还有其他变量(可能是 teamId 或 playerId)。 您的问题中一个非常不清楚的部分是您要分组的内容,所以请只关注这里的概念。第一个挑战是您没有 year 变量,并且有很多方法可以做到这一点。让我们做这样的事情:

df$gameYear <- as.POSIXlt(df$gameDate)$year + 1900 # see ?POSIXlt for more details

把它放在一起

使用链运算符%&gt;%,我们只需对我们已经查看过的内容进行排序。

library(dplyr)

cumsumLag1 <- function(x) cumsum(c(0, head(x, n = -1))) 

df %>%
    mutate(gameYear = as.POSIXlt(gameDate)$year + 1900) %>%
    arrange(gameDate) %>%
    group_by(gameYear) %>%
    mutate(priorAtBats = cumsumLag1(ab))

【讨论】:

  • 非常感谢 C8H10N402!这很有帮助。看起来我确实有一些约会要做,以及使用你的想法来组合蝙蝠。
  • 是的,我对我的术语感到困惑。我正在尝试 dput() 到目前为止我还没有得到它,但我会再看一遍。
  • 感谢大家,我有一组使用此功能的出色数据:
  • @Marianne 很高兴为您提供帮助,如果这回答了您的问题,请随时接受(点击复选标记)
猜你喜欢
  • 2014-04-12
  • 2019-12-01
  • 1970-01-01
  • 2015-09-11
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
相关资源
最近更新 更多