r - 使用 plyr 计算跨组的年同比变化的初学者提示

标签 r dataframe plyr

我是 plyr(和 R)的新手,正在寻找一些帮助来开始。以棒球数据集为例,我如何计算联赛和球队(lg 和球队)“击球数”的同比(yoy)变化?

library(plyr)
df1 <- aggregate(ab~year+lg+team, FUN=sum, data=baseball)

在做了一些聚合以简化数据名望后,数据看起来像这样:
head(df1)

  year lg team   ab
  1884 UA  ALT  108
  1997 AL  ANA 1703
  1998 AL  ANA 1502
  1999 AL  ANA  660
  2000 AL  ANA   85
  2001 AL  ANA  219

我想以这样的方式结束
  year lg team   ab yoy
  1997 AL  ANA 1703  NA
  1998 AL  ANA 1502  -201
  1999 AL  ANA  660  -842
  2000 AL  ANA   85  -575
  2001 AL  ANA  219  134

我首先写了以下函数,我认为这是错误的:
yoy.func <- function(df) {
  lag <- c(df$ab[-1],0)
  cur <- c(df$ab[1],0)
  df$yoy <- cur -lag
  return(df)
}

没有成功,我使用以下代码尝试返回 yoy 变化。
df2 <- ddply(df1, .(lg, team), yoy.func)

任何指导将不胜感激。

谢谢

最佳答案

我知道您要求特定于“plyr”的解决方案,但为了分享,这里是基础 R 中的替代方法。在我看来,我发现基础 R 方法“可读”。而且,至少在这种特殊情况下,它要快得多!

output <- within(df1, {
  yoy <- ave(ab, team, lg, FUN = function(x) c(NA, diff(x)))
})
head(output)
#   year lg team   ab  yoy
# 1 1884 UA  ALT  108   NA
# 2 1997 AL  ANA 1703   NA
# 3 1998 AL  ANA 1502 -201
# 4 1999 AL  ANA  660 -842
# 5 2000 AL  ANA   85 -575
# 6 2001 AL  ANA  219  134

library(rbenchmark)

benchmark(DDPLY = {
  ddply(df1, .(team, lg), mutate ,
        yoy = c(NA, diff(ab)))
}, WITHIN = {
  within(df1, {
    yoy <- ave(ab, team, lg, FUN = function(x) c(NA, diff(x)))
  })
}, columns = c("test", "replications", "elapsed", 
               "relative", "user.self"))
#     test replications elapsed relative user.self
# 1  DDPLY          100  10.675    4.974    10.609
# 2 WITHIN          100   2.146    1.000     2.128

更新:data.table
如果您的数据非常大,请查看 data.table .即使使用这个示例,您也会发现相对而言有很好的加速。此外,语法非常紧凑,在我看来,易于阅读。
library(plyr)
df1 <- aggregate(ab~year+lg+team, FUN=sum, data=baseball)
library(data.table)
DT <- data.table(df1)
DT
#       year lg team   ab
#    1: 1884 UA  ALT  108
#    2: 1997 AL  ANA 1703
#    3: 1998 AL  ANA 1502
#    4: 1999 AL  ANA  660
#    5: 2000 AL  ANA   85
#   ---                  
# 2523: 1895 NL  WSN  839
# 2524: 1896 NL  WSN  982
# 2525: 1897 NL  WSN 1426
# 2526: 1898 NL  WSN 1736
# 2527: 1899 NL  WSN  787

现在,看看这个简洁的解决方案:
DT[, yoy := c(NA, diff(ab)), by = "team,lg"]
DT
#       year lg team   ab  yoy
#    1: 1884 UA  ALT  108   NA
#    2: 1997 AL  ANA 1703   NA
#    3: 1998 AL  ANA 1502 -201
#    4: 1999 AL  ANA  660 -842
#    5: 2000 AL  ANA   85 -575
#   ---                       
# 2523: 1895 NL  WSN  839  290
# 2524: 1896 NL  WSN  982  143
# 2525: 1897 NL  WSN 1426  444
# 2526: 1898 NL  WSN 1736  310
# 2527: 1899 NL  WSN  787 -949

关于r - 使用 plyr 计算跨组的年同比变化的初学者提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14591147/

相关文章:

regex - 根据模式提取子串

r - 计数出现和未出现的出现

python - 如何对 groupby 中的 nlargest() 个整数求和

Python Pandas .where 具有超过 2 个可能的条件输入

r - ddply,按日期排列

r - optim() 错误 : searching for global minimum for a univariate function

python - 如何在 Spyder 窗口中获取大数据帧的最后一条记录?

r - 在 R 中按组向数据帧添加索引(或计数器)

R data.table 子集子集

删除空的分面类别